예제 #1
0
        /// <summary>
        /// Unmarshals and deallocates a OPCITEMSTATE structures.
        /// </summary>
        internal static DaValue[] GetItemValues(ref IntPtr pInput, int count, bool deallocate)
        {
            DaValue[] output = null;

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

                IntPtr pos = pInput;

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

                    DaValue value = new DaValue();

                    value.Value     = ComUtils.ProcessComValue(result.vDataValue);
                    value.Quality   = result.wQuality;
                    value.Timestamp = ComUtils.GetDateTime(result.ftTimeStamp);

                    output[ii] = value;

                    if (deallocate)
                    {
                        Marshal.DestroyStructure(pos, typeof(OpcRcw.Da.OPCITEMSTATE));
                    }

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

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

            return(output);
        }
예제 #2
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);
			}
		}