public static string GetFTSting(OpcRcw.Da.FILETIME ft)
 {
     long lFT = (((long)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
     //DateTime dt = DateTime.FromBinary(lFT);
     //DateTime dt = DateTime.FromFileTime(lFT);
     DateTime dt = DateTime.FromFileTimeUtc(lFT);
     //DateTime dt = DateTime.Now;
     return dt.ToString();
 }
        public void OnDataChange(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, 
            int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors)
        {
            //Получаем тип элемента данных
            IntPtr iptrValues = Marshal.AllocCoTaskMem(2);
            Marshal.GetNativeVariantForObject(pvValues, iptrValues);
            byte[] vt = new byte[2];
            Marshal.Copy(iptrValues, vt, 0, 2);
            Marshal.FreeCoTaskMem(iptrValues);
            ushort usVt = (ushort)(vt[0] + vt[1] * 255);

            Console.Write(m_szItemID + "---");
            Console.Write(ToStringConverter.GetVTString(usVt) + "---");
            Console.Write(pvValues[0].ToString() + "---");

            Console.Write(ToStringConverter.GetFTSting(pftTimeStamps[0]) + "---");
            Console.WriteLine(ToStringConverter.GetQualityString(pwQualities[0]));
        }
Example #3
0
        ///<summary>
        /// IOPCServer::CreateGroupEnumerator - Creates various enumerators for the groups provided by the Server.
        ///</summary>
		public void CreateGroupEnumerator(OpcRcw.Da.OPCENUMSCOPE dwScope, ref Guid riid, out object ppUnk)
		{
			lock (m_lock)
			{
				try
				{
					switch (dwScope)
					{
						case OPCENUMSCOPE.OPC_ENUM_PUBLIC:
						case OPCENUMSCOPE.OPC_ENUM_PUBLIC_CONNECTIONS:
						{
							if (riid == typeof(OpcRcw.Comn.IEnumString).GUID)
							{
								ppUnk = new EnumString(null);
                                return;
							}

							if (riid == typeof(OpcRcw.Comn.IEnumUnknown).GUID)
							{
								ppUnk = new EnumUnknown(null);
                                return;
							}

							throw ComUtils.CreateComException("E_NOINTERFACE", ResultIds.E_NOINTERFACE);
						}
					}

					if (riid == typeof(IEnumUnknown).GUID)
					{
						ppUnk = new EnumUnknown(m_groups);
                        return;
					}

					if (riid == typeof(OpcRcw.Comn.IEnumString).GUID)
					{
						ArrayList names = new ArrayList(m_groups.Count);

						foreach (string name in m_groups.Keys)
						{
							names.Add(name);
						}

						ppUnk = new EnumString(names);
                        return;
					}

					throw ComUtils.CreateComException("E_NOINTERFACE", ResultIds.E_NOINTERFACE);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
Example #4
0
        /// <summary>
        /// IOPCBrowseServerAddressSpace::BrowseOPCItemIDs - Gets an IENUMString for a list of ItemIDs as determined by the passed parameters.
        /// </summary>
		public void BrowseOPCItemIDs(
            OpcRcw.Da.OPCBROWSETYPE     dwBrowseFilterType, 
            string                      szFilterCriteria, 
            short                       vtDataTypeFilter, 
            int                         dwAccessRightsFilter, 
            out OpcRcw.Comn.IEnumString ppIEnumString)
		{
			lock (m_lock)
			{
				try
				{
                    // find the current node.
                    INode parent = null;

                    // ensure browse stack has been initialized.
                    if (m_browseStack.Count == 0)
                    {
                        parent = m_session.NodeCache.Find(Objects.ObjectsFolder);
                        m_browseStack.Push(parent);
                    }

                    parent = m_browseStack.Peek();

                    if (parent == null)
                    {
                        throw ComUtils.CreateComException(ResultIds.E_FAIL);
                    }

                    // apply filters.
                    List<INode> hits = new List<INode>();
                    
                    BrowseChildren(
                        parent,
                        dwBrowseFilterType,
                        szFilterCriteria,
                        vtDataTypeFilter,
                        dwAccessRightsFilter,
                        hits);

                    // build list of names to return.
                    Dictionary<string,INode> nodes = new Dictionary<string,INode>();
                    List<string> names = new List<string>();

                    foreach (INode child in hits)
                    {
                        string name = child.BrowseName.Name;

                        if (dwBrowseFilterType == OPCBROWSETYPE.OPC_FLAT)
                        {
                            name = NodeIdToItemId(child.NodeId);
                        }

                        if (!nodes.ContainsKey(name))
                        {
                            nodes.Add(name, child);
                            names.Add(name);
                        }
                    }

					// create enumerator.
					ppIEnumString = (OpcRcw.Comn.IEnumString)new EnumString(names);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
Example #5
0
        /// <summary>
        /// Browses the children of a node.
        /// </summary>
        private void BrowseChildren(
            INode                     parent,
            OpcRcw.Da.OPCBROWSETYPE   dwBrowseFilterType, 
            string                    szFilterCriteria, 
            short                     vtDataTypeFilter, 
            int                       dwAccessRightsFilter,
            List<INode>               hits)
        {
            Dictionary<string,INode> nodes = new Dictionary<string,INode>();

            // find children.
            IList<INode> children = m_session.NodeCache.Find(parent.NodeId, ReferenceTypeIds.HierarchicalReferences, false, true);

            foreach (INode child in children)
            {
                // ignore external nodes.
                if (child.NodeId.IsAbsolute)
                {
                    continue;
                }

                // ignore non-objects/variables.
                if ((child.NodeClass & (NodeClass.Object | NodeClass.Variable)) == 0)
                {
                    continue;
                }

                // ignore duplicate browse names.
                if (nodes.ContainsKey(child.BrowseName.Name))
                {
                    continue;
                }

                bool match = ApplyFilters(
                    child,
                    dwBrowseFilterType,
                    szFilterCriteria,
                    vtDataTypeFilter,
                    dwAccessRightsFilter);

                // add child.
                if (match)
                {
                    hits.Add(child);
                    nodes.Add(child.BrowseName.Name, child);
                }                 
                
                // recursively follow children when browsing flat.
                if (dwBrowseFilterType == OPCBROWSETYPE.OPC_FLAT)
                {
                    BrowseChildren(
                        child,
                        dwBrowseFilterType,
                        szFilterCriteria,
                        vtDataTypeFilter,
                        dwAccessRightsFilter,
                        hits);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Applies the browse filters to a node.
        /// </summary>
        private bool ApplyFilters(
            INode                     child,
            OpcRcw.Da.OPCBROWSETYPE   dwBrowseFilterType, 
            string                    szFilterCriteria, 
            short                     vtDataTypeFilter, 
            int                       dwAccessRightsFilter)
        {
            bool hasChildren = HasChildren(child);   

            // apply branch filter.
            if (dwBrowseFilterType == OPCBROWSETYPE.OPC_BRANCH && !hasChildren)
            {
                return false;
            }

            // apply leaf filter.
            if (dwBrowseFilterType == OPCBROWSETYPE.OPC_LEAF && hasChildren)
            {
                return false;
            }

            // check for items.                                
            bool isItem = IsItem(child);

            if (!isItem && !hasChildren)
            {
                return false;
            }

            // apply flat filter.
            if (dwBrowseFilterType == OPCBROWSETYPE.OPC_FLAT && !isItem)
            {
                return false;
            }

            // apply name filter.
            if (dwBrowseFilterType != OPCBROWSETYPE.OPC_FLAT)
            {
                if (!String.IsNullOrEmpty(szFilterCriteria))
                {
                    if (!ComUtils.Match(child.BrowseName.Name, szFilterCriteria, true))
                    {
                        return false;
                    }
                }
            }
            
            // check for variable.
            VariableNode variable = child as VariableNode;

            if (variable != null)
            {
				// apply access right filter. 
				if (dwAccessRightsFilter != 0) 
				{ 
					if (dwAccessRightsFilter == OpcRcw.Da.Constants.OPC_READABLE && ((variable.AccessLevel & AccessLevels.CurrentRead) == 0)) 
					{ 
                        return false;
					} 
                    
					if (dwAccessRightsFilter == OpcRcw.Da.Constants.OPC_WRITEABLE && ((variable.AccessLevel & AccessLevels.CurrentWrite) == 0)) 
					{ 
                        return false;
					} 
				} 

                // lookup the requested datatype.
                if (vtDataTypeFilter != 0)
                {
                    bool isArray = false;
                    NodeId requestedDataTypeId = ComUtils.GetDataTypeId(vtDataTypeFilter, out isArray);

                    VarEnum varType = DataTypeToVarType(variable.DataType, variable.ValueRank);

                    if (varType != VarEnum.VT_VARIANT && (short)varType != vtDataTypeFilter)
                    {
                        return false;
                    }
                }

                // must match item id rather than name when browsing flat.
                if (dwBrowseFilterType == OPCBROWSETYPE.OPC_FLAT)
                {
                    if (!String.IsNullOrEmpty(szFilterCriteria))
                    {
                        string itemId = NodeIdToItemId(child.NodeId);

                        if (!ComUtils.Match(itemId, szFilterCriteria, true))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
 /// <remarks/>
 public void GetConnectionPointContainer(out OpcRcw.Comn.IConnectionPointContainer ppCPC)
 {
     lock (m_lock)
     {
         try
         {
             ppCPC = m_container;
         }
         catch (Exception e)
         {
             throw ComUtils.CreateComException(e);
         }
     }
 }
Example #8
0
 public virtual void OnReadComplete(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors)
 {
 }
Example #9
0
 void IOPCDataCallback.OnReadComplete(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors)
 {
     throw new Exception("The method or operation is not implemented.");
 }
Example #10
0
        /// <summary>
        /// Updates the server status structure with the values from the server.
        /// </summary>
        private void UpdateServerStatus(ref OpcRcw.Da.OPCSERVERSTATUS status)
        {
            // read the current status.
            ReadValueId nodeToRead  = new ReadValueId();

            nodeToRead.NodeId       = Opc.Ua.Variables.Server_ServerStatus;
            nodeToRead.AttributeId  = Attributes.Value;
            nodeToRead.DataEncoding = null;
            nodeToRead.IndexRange   = null;

            ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
            nodesToRead.Add(nodeToRead);

            DataValueCollection values = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.Read(
                null,
                0,
                TimestampsToReturn.Neither,
                nodesToRead,
                out values,
                out diagnosticInfos);
            
            // validate response from the UA server.
            ClientBase.ValidateResponse(values, nodesToRead);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);

            // check for read error.
            if (StatusCode.IsBad(values[0].StatusCode))
            {
                return;
            }

            // get remote status.
            ServerStatusDataType remoteStatus = ExtensionObject.ToEncodeable(values[0].Value as ExtensionObject) as ServerStatusDataType;

            if (remoteStatus == null)
            {
                return;
            }

            // extract the times.
            status.ftStartTime   = ComUtils.GetFILETIME(remoteStatus.StartTime);
            status.ftCurrentTime = ComUtils.GetFILETIME(remoteStatus.CurrentTime);

            // convert the server state.          
            switch (remoteStatus.State)
            {
                case ServerState.Running:               { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_RUNNING; break; }
                case ServerState.Suspended:             { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_SUSPENDED; break; }
                case ServerState.CommunicationFault:    { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_COMM_FAULT; break; }
                case ServerState.Failed:                { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_FAILED; break; }
                case ServerState.NoConfiguration:       { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_NOCONFIG; break; }
                case ServerState.Test:                  { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_TEST; break; }
                default:                                { status.dwServerState = OPCSERVERSTATE.OPC_STATUS_FAILED; break; }
            }

            BuildInfo buildInfo = remoteStatus.BuildInfo;

            // construct the vendor info.
            status.szVendorInfo = String.Format("{0}, {1}", buildInfo.ProductName, buildInfo.ManufacturerName);

            // parse the software version.
            if (!String.IsNullOrEmpty(buildInfo.SoftwareVersion))
            {
                string[] fields = buildInfo.SoftwareVersion.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

                if (fields.Length > 0)
                {
                    status.wMajorVersion = ExtractVersionFromString(fields[0]);
                }
                
                if (fields.Length > 1)
                {
                    status.wMinorVersion = ExtractVersionFromString(fields[1]);
                }
            }

            if (!String.IsNullOrEmpty(buildInfo.BuildNumber))
            {                        
                string[] fields = buildInfo.SoftwareVersion.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

                if (fields.Length > 0)
                {
                    status.wBuildNumber = ExtractVersionFromString(fields[0]);
                }
            }
        }
Example #11
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^//
        #region IOPCSyncIO Members
        /// <summary>
        /// IOPCSyncIO::Read - Reads the value, quality and timestamp information for one or more items in a group
        /// </summary>
		public void Read(
            OpcRcw.Da.OPCDATASOURCE dwSource, 
            int                     dwCount, 
            int[]                   phServer, 
            out System.IntPtr       ppItemValues, 
            out System.IntPtr       ppErrors)
		{
            // validate arguments.
            if (dwCount == 0 || phServer == null || dwCount != phServer.Length)
            {
                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
            }

			try
			{
				OpcRcw.Da.OPCITEMSTATE[] results = new OpcRcw.Da.OPCITEMSTATE[dwCount];
                int[] errors = new int[dwCount];
                VarEnum[] reqTypes = new VarEnum[dwCount];

                // use the minimum max age for all items.
                int maxAge = (dwSource == OPCDATASOURCE.OPC_DS_CACHE)?Int32.MaxValue:0;

                // build list of values to read.
                ReadValueIdCollection nodesToRead = new ReadValueIdCollection();
                List<Item> itemsToRead = new List<Item>();
                        
		        lock (m_lock)
		        {
			        if (m_subscription == null) throw ComUtils.CreateComException(ResultIds.E_FAIL);

                    for (int ii = 0; ii < dwCount; ii++)
                    {
                        results[ii].hClient     = 0;
                        results[ii].vDataValue  = null;
                        results[ii].wQuality    = OpcRcw.Da.Qualities.OPC_QUALITY_BAD;  
                        results[ii].ftTimeStamp = ComUtils.GetFILETIME(DateTime.MinValue);
                        results[ii].wReserved   = 0;

                        Item itemToRead = null;

                        if (!m_items.TryGetValue(phServer[ii], out itemToRead))
                        {
                            errors[ii] = ResultIds.E_INVALIDHANDLE;
                            continue;
                        }

                        results[ii].hClient = itemToRead.ClientHandle;

                        // check if reading from the cache.
                        if (dwSource == OPCDATASOURCE.OPC_DS_CACHE)
                        {
                            // read the value from cache.
                            DataValue cachedValue = ReadCachedValue(itemToRead, Int32.MaxValue);

                            if (cachedValue != null)
                            {
                                // get value from the cache.
                                object value = null;
                                short quality = Qualities.OPC_QUALITY_BAD;
                                DateTime timestamp = DateTime.MinValue;

                                errors[ii] = ProcessReadResult(
                                    phServer[ii],
                                    itemToRead.ReqType,
                                    cachedValue,
                                    out value,
                                    out quality,
                                    out timestamp);

                                // all done if a suitable value is in the cache.
                                if (!m_active || !itemToRead.Active)
                                {
                                    quality = Qualities.OPC_QUALITY_OUT_OF_SERVICE;
                                }

                                results[ii].vDataValue  = value;
                                results[ii].wQuality    = quality; 
                                results[ii].ftTimeStamp = ComUtils.GetFILETIME(timestamp); 
                                continue;
                            }
                        }

                        // save the requested data type.
                        reqTypes[ii] = itemToRead.ReqType;

                        ReadValueId nodeToRead = new ReadValueId();

                        nodeToRead.NodeId      = itemToRead.MonitoredItem.ResolvedNodeId;
                        nodeToRead.AttributeId = Attributes.Value;

                        // needed to correlate results to input.
                        nodeToRead.Handle = ii;

                        nodesToRead.Add(nodeToRead);
                        itemsToRead.Add(itemToRead);
                    }
                }
                    
                // read values from server.
                DataValueCollection values = null;
                DiagnosticInfoCollection diagnosticInfos = null;
                
                if (nodesToRead.Count > 0)
                {
                    m_session.Read(
                        null,
                        maxAge,
                        TimestampsToReturn.Both,
                        nodesToRead,
                        out values,
                        out diagnosticInfos);
                
                    // validate response from the UA server.
                    ClientBase.ValidateResponse(values, nodesToRead);
                    ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToRead);
                }
                
                for (int ii = 0; ii < nodesToRead.Count; ii++)
                {
                    // get index in original array.
                    int index = (int)nodesToRead[ii].Handle;
                                     
                    // process the read result.
                    object value = null;
                    short quality = Qualities.OPC_QUALITY_BAD;
                    DateTime timestamp = DateTime.MinValue;

                    int error = ProcessReadResult(
                        phServer[index], 
                        reqTypes[index], 
                        values[ii],
                        out value, 
                        out quality,
                        out timestamp);

                    // update the cache.
                    UpdateCachedValue(itemsToRead[ii], values[ii]);

                    // check for error.
                    if (error < 0)
                    {                            
                        errors[index] = error;
                        continue;
                    }

                    // update response.                                            
                    results[index].vDataValue  = value;
                    results[index].wQuality    = quality; 
                    results[index].ftTimeStamp = ComUtils.GetFILETIME(timestamp);  
                  
                    errors[index] = ResultIds.S_OK;
                }
                
                // marshal the results.
                ppItemValues = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(OPCITEMSTATE))*dwCount);
                IntPtr pos = ppItemValues;
                                    
                for (int ii = 0; ii < dwCount; ii++)
                {
                    Marshal.StructureToPtr(results[ii], pos, false);
                    pos = (IntPtr)(pos.ToInt32() + Marshal.SizeOf(typeof(OpcRcw.Da.OPCITEMSTATE)));
                }
                
				// marshal error codes.
				ppErrors = ComUtils.GetInt32s(errors);
			}
			catch (Exception e)
			{
                Utils.Trace(e, "Error reading items.");
				throw ComUtils.CreateComException(e);
			}
		}
Example #12
0
        /// <summary>
        /// IOPCAsyncIO2::Refresh2 - Forces a callback to IOPCDataCallback::OnDataChange for all active items 
        ///                          in the group (whether they have changed or not). Inactive items are not included in the callback.
        /// </summary>
		public void Refresh2(
            OpcRcw.Da.OPCDATASOURCE dwSource, 
            int dwTransactionID, 
            out int pdwCancelID)
		{
			// calculate max age.
			int maxAge = (dwSource == OPCDATASOURCE.OPC_DS_DEVICE)?0:Int32.MaxValue;

			// call refresh.
			RefreshMaxAge(maxAge, dwTransactionID, out pdwCancelID);
		}
Example #13
0
		/// <remarks/>
		public void Clone(out OpcRcw.Comn.IEnumString ppenum)
		{
			lock (m_lock)
			{
				try
				{
					ppenum = new EnumString(m_strings);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
		/// <remarks/>
        public void Clone(out OpcRcw.Comn.IEnumConnectionPoints ppenum)
		{
			lock (m_lock)
			{
				try
				{
					ppenum = new EnumConnectionPoints(m_connectionPoints);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
 /// <remarks/>
 public void EnumConnections(out OpcRcw.Comn.IEnumConnections ppenum)
 {
     throw new ExternalException("E_NOTIMPL", ResultIds.E_NOTIMPL);
 }
Example #16
0
        /// <summary>
        /// IOPCBrowseServerAddressSpace::BrowseAccessPaths - Provides a way to browse the available AccessPaths for an item ID - not supported.
        /// </summary>
		public void BrowseAccessPaths(
            string                      szItemID, 
            out OpcRcw.Comn.IEnumString ppIEnumString)
		{
			lock (m_lock)
			{
				// access paths not supported.
				try
				{
					throw ComUtils.CreateComException("BrowseAccessPaths", ResultIds.E_NOTIMPL);
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
Example #17
0
 void IOPCDataCallback.OnDataChange(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors)
 {
     this.OnDataChange(dwTransid, hGroup, hrMasterquality, hrMastererror, dwCount, phClientItems, pvValues, pwQualities, pftTimeStamps, pErrors);
 }
Example #18
0
        /// <summary>
        /// IOPCBrowseServerAddressSpace::QueryOrganization - Determines if the ServerAddressSpace is flat or hierarchical.
        /// </summary>
		public void QueryOrganization(out OpcRcw.Da.OPCNAMESPACETYPE pNameSpaceType)
		{
			lock (m_lock)
			{
				// only hierarchial spaces supported.
				try
				{
					pNameSpaceType = OPCNAMESPACETYPE.OPC_NS_HIERARCHIAL;
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}

            // return ResultIds.S_OK;
		}
Example #19
0
 public virtual void OnDataChange(int dwTransid, int hGroup, int hrMasterquality, int hrMastererror, int dwCount, int[] phClientItems, object[] pvValues, short[] pwQualities, OpcRcw.Da.FILETIME[] pftTimeStamps, int[] pErrors)
 {
     for (int i = 0; i < dwCount; i++)
     {
         object[] objArray;
         OPCItem item = this.items[phClientItems[i]];
         if (pvValues[i] is Array)
         {
             Array array = (Array) pvValues[i];
             objArray = new object[array.Length];
             for (int j = 0; j < array.Length; j++)
             {
                 objArray[j] = array.GetValue(j);
             }
         }
         else
         {
             objArray = new object[] { pvValues[i] };
         }
         if (this.OnDataChanged != null)
         {
             this.OnDataChanged(this, new DataChangedEventArgs(this.parent.ServerName, this.groupName, item.ItemName, objArray));
         }
     }
 }
Example #20
0
        /// <summary>
        /// IOPCBrowseServerAddressSpace::ChangeBrowsePosition - Provides a way to move UP or DOWN or TO in a hierarchical space.
        /// </summary>
		public void ChangeBrowsePosition(OpcRcw.Da.OPCBROWSEDIRECTION dwBrowseDirection, string szString)
		{
			lock (m_lock)
			{
				try
                {
                    switch (dwBrowseDirection)
                    {
                        // move to a specified position or root.
                        case OPCBROWSEDIRECTION.OPC_BROWSE_TO:
                        {
                            // move to root.
                            if (String.IsNullOrEmpty(szString))
                            {
                                m_browseStack.Clear();
                                m_browseStack.Push(m_session.NodeCache.Find(Objects.ObjectsFolder));
                                break;
                            }
                            
                            // parse the item id.
                            NodeId nodeId = ItemIdToNodeId(szString);

                            if (nodeId == null)
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }
                            
                            // find the current node.
                            INode node = m_session.NodeCache.Find(nodeId);

                            if (node == null)
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // only can browse to branch
                            if (!HasChildren(node))
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // build a new browse stack.
                            Stack<INode> browseStack = new Stack<INode>();

                            if (!FindPathToNode(node, browseStack))
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // push target node onto stack.
                            browseStack.Push(m_session.NodeCache.Find(nodeId));
                            
                            m_browseStack = browseStack;
                            break;
                        }

                        // move to a child branch.
                        case OPCBROWSEDIRECTION.OPC_BROWSE_DOWN:
                        {
                            // check for invalid name.
                            if (String.IsNullOrEmpty(szString))
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // find the current node.
                            INode parent = m_browseStack.Peek();

                            if (parent == null)
                            {
                                throw ComUtils.CreateComException(ResultIds.E_FAIL);
                            }

                            // find the child.
                            INode child = FindChildByName(parent.NodeId, szString);
                            
                            if (child == null)
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }
                            
                            // only can browse to branch
                            if (!HasChildren(child))
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // save the new position.
                            m_browseStack.Push(child);
                            break;
                        }

                        // move to a parent branch.
                        case OPCBROWSEDIRECTION.OPC_BROWSE_UP:
                        {
                            // check for invalid name.
                            if (!String.IsNullOrEmpty(szString))
                            {
                                throw ComUtils.CreateComException(ResultIds.E_INVALIDARG);
                            }

                            // can't move up from root.
                            if (m_browseStack.Count <= 1)
                            {
                                throw ComUtils.CreateComException(ResultIds.E_FAIL);
                            }

                            // move up the stack.
                            m_browseStack.Pop();
                            break;
                        }

                        default:
                        {
                            throw ComUtils.CreateComException(ResultIds.E_FAIL);
                        }
                    }
                }
                catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}
Example #21
0
        /// <summary>
        /// Return an IEnumString for a list of Areas as determined by the passed parameters.
        /// </summary>
        /// <param name="dwBrowseFilterType">
        /// OPC_AREA - returns only areas.
        /// OPC_SOURCE - returns only sources.</param>
        /// <param name="szFilterCriteria">A server specific filter string. A pointer to a NULL string indicates no filtering.</param>
        /// <param name="ppIEnumString">Where to save the returned interface pointer. NULL if the HRESULT is other than S_OK or S_FALSE.</param>
        public void BrowseOPCAreas(
            OPCAEBROWSETYPE             dwBrowseFilterType, 
            string                      szFilterCriteria, 
            out OpcRcw.Comn.IEnumString ppIEnumString)
        {
            ppIEnumString = null;
            if (dwBrowseFilterType != OPCAEBROWSETYPE.OPC_AREA && dwBrowseFilterType != OPCAEBROWSETYPE.OPC_SOURCE)
            {
                throw ComUtils.CreateComException("BrowseOPCAreas", ResultIds.E_INVALIDARG);
            }
            try
            {
                lock (m_lock)
                {
                    // find the current node.
                    INode parent = null;

                    // ensure browse stack has been initialized.
                    if (m_browseStack.Count == 0)
                    {
                        parent = m_session.NodeCache.Find(Objects.Server);
                        m_browseStack.Push(parent);
                    }

                    parent = m_browseStack.Peek();

                    if (parent == null)
                    {
                        throw ComUtils.CreateComException("BrowseOPCAreas",ResultIds.E_FAIL);
                    }

                    List<string> names = new List<string>();
                    IList<INode> children;

                    ////// find children.
                       children = m_session.NodeCache.Find(parent.NodeId, ReferenceTypes.HasEventSource, false, true); // This would also include 
                                                                                                                        // the HasNotifier reference which is 
                                                                                                                        // a subtype of HasEventSource 

                    foreach (INode child in children)
                    {
                        // ignore external nodes.
                        if (child.NodeId.IsAbsolute)
                        {
                            continue;
                        }

                        // ignore non-objects/variables.
                        if ((child.NodeClass & (NodeClass.Object | NodeClass.Variable)) == 0)
                        {
                            continue;
                        }

                        // ignore duplicate browse names.
                        if (names.Contains(child.BrowseName.ToString()))
                        {
                            continue;
                        }

                        // For a node to be an area, it has to have the 'HasNotifier' reference and must
                        // allow event notification (the EventNotifier attribute is set to SubscribeToEvents) 
                        // For a node to be a source, it should be the target of the HasEventSource reference
                        if (IsValidNode((NodeId)child.NodeId, child.BrowseName.ToString(), dwBrowseFilterType))
                        {
                            if (String.IsNullOrEmpty(szFilterCriteria))
                            {
                                names.Add(child.BrowseName.ToString());
                            }
                            else
                            {
                                // apply filters
                                if (ComUtils.Match(child.BrowseName.ToString(), szFilterCriteria, true))
                                {
                                   names.Add(child.BrowseName.ToString());
                                }
                            }
                        }
                     }

                    // create enumerator.
                    ppIEnumString = (OpcRcw.Comn.IEnumString)new EnumString(names);
                }
            }
            catch (Exception e)
            {
                Utils.Trace(e, "Unexpected error in BrowseOPCAreas");
                throw ComUtils.CreateComException(e);
            }
        }
		/// <remarks/>
        public void FindConnectionPoint(ref Guid riid, out OpcRcw.Comn.IConnectionPoint ppCP)
		{
			lock (m_lock)
			{
				try
				{
					ppCP = null;

					ConnectionPoint connectionPoint = (ConnectionPoint)m_connectionPoints[riid];

					if (connectionPoint == null)
					{
						throw new ExternalException("CONNECT_E_NOCONNECTION", ResultIds.CONNECT_E_NOCONNECTION);
					}

                    ppCP = connectionPoint as IConnectionPoint;
				}
				catch (Exception e)
				{
					throw ComUtils.CreateComException(e);
				}
			}
		}