Example #1
0
        /// <summary>
        /// Reads an error from a stream.
        /// </summary>
        protected static ServiceResult ReadErrorMessageBody(BinaryDecoder decoder)
        {
            // read the status code.
            uint statusCode = decoder.ReadUInt32(null);

            string reason = null;

            // ensure the reason does not exceed the limits in the protocol.
            int reasonLength = decoder.ReadInt32(null);

            if (reasonLength > 0 && reasonLength < TcpMessageLimits.MaxErrorReasonLength)
            {
                byte[] reasonBytes = new byte[reasonLength];

                for (int ii = 0; ii < reasonLength; ii++)
                {
                    reasonBytes[ii] = decoder.ReadByte(null);
                }

                reason = new UTF8Encoding().GetString(reasonBytes, 0, reasonLength);
            }

            // Utils.Trace("Channel {0}: Read = {1}", ChannelId, reason);

            return(ServiceResult.Create(statusCode, "Error received from remote host: {0}", reason));
        }
Example #2
0
        /// <summary>
        /// Updates the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="decoder">The decoder.</param>
        /// <param name="attibutesToLoad">The attributes to load.</param>
        public override void Update(ISystemContext context, BinaryDecoder decoder, AttributesToSave attibutesToLoad)
        {
            base.Update(context, decoder, attibutesToLoad);

            if ((attibutesToLoad & AttributesToSave.Value) != 0)
            {
                WrappedValue = decoder.ReadVariant(null);
            }

            if ((attibutesToLoad & AttributesToSave.DataType) != 0)
            {
                m_dataType = decoder.ReadNodeId(null);
            }

            if ((attibutesToLoad & AttributesToSave.ValueRank) != 0)
            {
                m_valueRank = decoder.ReadInt32(null);
            }

            if ((attibutesToLoad & AttributesToSave.ArrayDimensions) != 0)
            {
                UInt32Collection arrayDimensions = decoder.ReadUInt32Array(null);

                if (arrayDimensions != null && arrayDimensions.Count > 0)
                {
                    m_arrayDimensions = new ReadOnlyList <uint>(arrayDimensions);
                }
                else
                {
                    m_arrayDimensions = null;
                }
            }
        }
        /// <summary>
        /// Reads the schema information from a XML document.
        /// </summary>
        public void LoadFromBinary(ISystemContext context, Stream istrm, bool updateTables)
        {
            ServiceMessageContext messageContext = new ServiceMessageContext();

            messageContext.NamespaceUris = context.NamespaceUris;
            messageContext.ServerUris    = context.ServerUris;
            messageContext.Factory       = context.EncodeableFactory;

            using (BinaryDecoder decoder = new BinaryDecoder(istrm, messageContext))
            {
                // check if a namespace table was provided.
                NamespaceTable namespaceUris = new NamespaceTable();

                if (!decoder.LoadStringTable(namespaceUris))
                {
                    namespaceUris = null;
                }

                // update namespace table.
                if (updateTables)
                {
                    if (namespaceUris != null && context.NamespaceUris != null)
                    {
                        for (int ii = 0; ii < namespaceUris.Count; ii++)
                        {
                            context.NamespaceUris.GetIndexOrAppend(namespaceUris.GetString((uint)ii));
                        }
                    }
                }

                // check if a server uri table was provided.
                StringTable serverUris = new StringTable();

                if (namespaceUris != null && namespaceUris.Count > 1)
                {
                    serverUris.Append(namespaceUris.GetString(1));
                }

                if (!decoder.LoadStringTable(serverUris))
                {
                    serverUris = null;
                }

                // update server table.
                if (updateTables)
                {
                    if (serverUris != null && context.ServerUris != null)
                    {
                        for (int ii = 0; ii < serverUris.Count; ii++)
                        {
                            context.ServerUris.GetIndexOrAppend(serverUris.GetString((uint)ii));
                        }
                    }
                }

                // setup the mappings to use during decoding.
                decoder.SetMappingTables(namespaceUris, serverUris);

                int count = decoder.ReadInt32(null);

                for (int ii = 0; ii < count; ii++)
                {
                    NodeState state = NodeState.LoadNode(context, decoder);
                    this.Add(state);
                }
            }
        }
        private bool ProcessHelloMessage(uint messageType, ArraySegment<byte> messageChunk)
        {
            // validate the channel state.            
            if (State != TcpChannelState.Connecting)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected Hello message.");
                return false;
            }
         
            try
            {
                MemoryStream istrm = new MemoryStream(messageChunk.Array, messageChunk.Offset, messageChunk.Count, false);
                BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);
                istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

                // read requested buffer sizes.
                uint protocolVersion = decoder.ReadUInt32(null);  
                uint receiveBufferSize = decoder.ReadUInt32(null); 
                uint sendBufferSize = decoder.ReadUInt32(null); 
                uint maxMessageSize = decoder.ReadUInt32(null); 
                uint maxChunkCount = decoder.ReadUInt32(null); 
                
                // read the endpoint url.
                int length = decoder.ReadInt32(null);

                if (length > 0)
                {
                    if (length > TcpMessageLimits.MaxEndpointUrlLength)
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return false;
                    }

                    byte[] endpointUrl = new byte[length];

                    for (int ii = 0; ii < endpointUrl.Length; ii++)
                    {
                        endpointUrl[ii] = decoder.ReadByte(null);
                    }

                    if (!SetEndpointUrl(new UTF8Encoding().GetString(endpointUrl)))
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return false;
                    }
                }
                
                decoder.Close();

                // update receive buffer size.
                if (receiveBufferSize < ReceiveBufferSize)
                {
                    ReceiveBufferSize = (int)receiveBufferSize;
                }

                if (ReceiveBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    ReceiveBufferSize = TcpMessageLimits.MinBufferSize;
                }
                
                // update send buffer size.
                if (sendBufferSize < SendBufferSize)
                {
                    SendBufferSize = (int)sendBufferSize;
                }

                if (SendBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    SendBufferSize = TcpMessageLimits.MinBufferSize;
                }            
                
                // update the max message size.
                if (maxMessageSize > 0 && maxMessageSize < MaxResponseMessageSize)
                {
                    MaxResponseMessageSize = (int)maxMessageSize;
                }
                
                if (MaxResponseMessageSize < SendBufferSize)
                {
                    MaxResponseMessageSize = SendBufferSize;
                }

                // update the max chunk count.
                if (maxChunkCount > 0 && maxChunkCount < MaxResponseChunkCount)
                {
                    MaxResponseChunkCount = (int)maxChunkCount;
                }
                
                // send acknowledge.
                byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "ProcessHelloMessage");
                
                try
                {
                    MemoryStream ostrm = new MemoryStream(buffer, 0, SendBufferSize);
                    BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);
                    
                    encoder.WriteUInt32(null, TcpMessageType.Acknowledge);
                    encoder.WriteUInt32(null, 0);
                    encoder.WriteUInt32(null, 0); // ProtocolVersion
                    encoder.WriteUInt32(null, (uint)ReceiveBufferSize);
                    encoder.WriteUInt32(null, (uint)SendBufferSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestMessageSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestChunkCount);
                    
                    int size = encoder.Close();
                    UpdateMessageSize(buffer, 0, size);
                                                
                    // now ready for the open or bind request.
                    State = TcpChannelState.Opening;

                    BeginWriteMessage(new ArraySegment<byte>(buffer, 0, size), Int32.MaxValue, null);
                    buffer = null;
                }
                finally
                {
                    if (buffer != null)
                    {
                        BufferManager.ReturnBuffer(buffer, "ProcessHelloMessage");
                    }
                }
            }
            catch (Exception e)
            {
                ForceChannelFault(e, StatusCodes.BadTcpInternalError, "Unexpected error while processing a Hello message.");
            }

            return false;
        }
        private bool ProcessHelloMessage(ArraySegment <byte> messageChunk)
        {
            // validate the channel state.
            if (State != TcpChannelState.Connecting)
            {
                ForceChannelFault(StatusCodes.BadTcpMessageTypeInvalid, "Client sent an unexpected Hello message.");
                return(false);
            }

            try
            {
                MemoryStream  istrm   = new MemoryStream(messageChunk.Array, messageChunk.Offset, messageChunk.Count, false);
                BinaryDecoder decoder = new BinaryDecoder(istrm, Quotas.MessageContext);
                istrm.Seek(TcpMessageLimits.MessageTypeAndSize, SeekOrigin.Current);

                // read requested buffer sizes.
                uint protocolVersion   = decoder.ReadUInt32(null);
                uint receiveBufferSize = decoder.ReadUInt32(null);
                uint sendBufferSize    = decoder.ReadUInt32(null);
                uint maxMessageSize    = decoder.ReadUInt32(null);
                uint maxChunkCount     = decoder.ReadUInt32(null);

                // read the endpoint url.
                int length = decoder.ReadInt32(null);

                if (length > 0)
                {
                    if (length > TcpMessageLimits.MaxEndpointUrlLength)
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return(false);
                    }

                    byte[] endpointUrl = new byte[length];

                    for (int ii = 0; ii < endpointUrl.Length; ii++)
                    {
                        endpointUrl[ii] = decoder.ReadByte(null);
                    }

                    if (!SetEndpointUrl(new UTF8Encoding().GetString(endpointUrl, 0, endpointUrl.Length)))
                    {
                        ForceChannelFault(StatusCodes.BadTcpEndpointUrlInvalid);
                        return(false);
                    }
                }

                decoder.Close();

                // update receive buffer size.
                if (receiveBufferSize < ReceiveBufferSize)
                {
                    ReceiveBufferSize = (int)receiveBufferSize;
                }

                if (ReceiveBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    ReceiveBufferSize = TcpMessageLimits.MinBufferSize;
                }

                // update send buffer size.
                if (sendBufferSize < SendBufferSize)
                {
                    SendBufferSize = (int)sendBufferSize;
                }

                if (SendBufferSize < TcpMessageLimits.MinBufferSize)
                {
                    SendBufferSize = TcpMessageLimits.MinBufferSize;
                }

                // update the max message size.
                if (maxMessageSize > 0 && maxMessageSize < MaxResponseMessageSize)
                {
                    MaxResponseMessageSize = (int)maxMessageSize;
                }

                if (MaxResponseMessageSize < SendBufferSize)
                {
                    MaxResponseMessageSize = SendBufferSize;
                }

                // update the max chunk count.
                if (maxChunkCount > 0 && maxChunkCount < MaxResponseChunkCount)
                {
                    MaxResponseChunkCount = (int)maxChunkCount;
                }

                // send acknowledge.
                byte[] buffer = BufferManager.TakeBuffer(SendBufferSize, "ProcessHelloMessage");

                try
                {
                    MemoryStream  ostrm   = new MemoryStream(buffer, 0, SendBufferSize);
                    BinaryEncoder encoder = new BinaryEncoder(ostrm, Quotas.MessageContext);

                    encoder.WriteUInt32(null, TcpMessageType.Acknowledge);
                    encoder.WriteUInt32(null, 0);
                    encoder.WriteUInt32(null, 0); // ProtocolVersion
                    encoder.WriteUInt32(null, (uint)ReceiveBufferSize);
                    encoder.WriteUInt32(null, (uint)SendBufferSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestMessageSize);
                    encoder.WriteUInt32(null, (uint)MaxRequestChunkCount);

                    int size = encoder.Close();
                    UpdateMessageSize(buffer, 0, size);

                    // now ready for the open or bind request.
                    State = TcpChannelState.Opening;

                    BeginWriteMessage(new ArraySegment <byte>(buffer, 0, size), null);
                    buffer = null;
                }
                finally
                {
                    if (buffer != null)
                    {
                        BufferManager.ReturnBuffer(buffer, "ProcessHelloMessage");
                    }
                }
            }
            catch (Exception e)
            {
                ForceChannelFault(e, StatusCodes.BadTcpInternalError, "Unexpected error while processing a Hello message.");
            }

            return(false);
        }
Example #6
0
        /// <summary>
        /// Decode a scalar type
        /// </summary>
        /// <param name="binaryDecoder"></param>
        /// <param name="builtInType"></param>
        /// <returns>The decoded object</returns>
        private object DecodeRawScalar(BinaryDecoder binaryDecoder, byte builtInType)
        {
            switch ((BuiltInType)builtInType)
            {
            case BuiltInType.Boolean:
                return(binaryDecoder.ReadBoolean(null));

            case BuiltInType.SByte:
                return(binaryDecoder.ReadSByte(null));

            case BuiltInType.Byte:
                return(binaryDecoder.ReadByte(null));

            case BuiltInType.Int16:
                return(binaryDecoder.ReadInt16(null));

            case BuiltInType.UInt16:
                return(binaryDecoder.ReadUInt16(null));

            case BuiltInType.Int32:
                return(binaryDecoder.ReadInt32(null));

            case BuiltInType.UInt32:
                return(binaryDecoder.ReadUInt32(null));

            case BuiltInType.Int64:
                return(binaryDecoder.ReadInt64(null));

            case BuiltInType.UInt64:
                return(binaryDecoder.ReadUInt64(null));

            case BuiltInType.Float:
                return(binaryDecoder.ReadFloat(null));

            case BuiltInType.Double:
                return(binaryDecoder.ReadDouble(null));

            case BuiltInType.String:
                return(binaryDecoder.ReadString(null));

            case BuiltInType.DateTime:
                return(binaryDecoder.ReadDateTime(null));

            case BuiltInType.Guid:
                return(binaryDecoder.ReadGuid(null));

            case BuiltInType.ByteString:
                return(binaryDecoder.ReadByteString(null));

            case BuiltInType.XmlElement:
                return(binaryDecoder.ReadXmlElement(null));

            case BuiltInType.NodeId:
                return(binaryDecoder.ReadNodeId(null));

            case BuiltInType.ExpandedNodeId:
                return(binaryDecoder.ReadExpandedNodeId(null));

            case BuiltInType.StatusCode:
                return(binaryDecoder.ReadStatusCode(null));

            case BuiltInType.QualifiedName:
                return(binaryDecoder.ReadQualifiedName(null));

            case BuiltInType.LocalizedText:
                return(binaryDecoder.ReadLocalizedText(null));

            case BuiltInType.DataValue:
                return(binaryDecoder.ReadDataValue(null));

            case BuiltInType.Enumeration:
                return(binaryDecoder.ReadInt32(null));

            case BuiltInType.Variant:
                return(binaryDecoder.ReadVariant(null));

            case BuiltInType.ExtensionObject:
                return(binaryDecoder.ReadExtensionObject(null));

            default:
                return(null);
            }
        }
Example #7
0
        /// <summary>
        /// Acknowledges the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="eventId">The event id.</param>
        /// <param name="comment">The comment.</param>
        /// <returns></returns>
        public uint Acknowledge(
            ServerSystemContext context,
            byte[] eventId,
            LocalizedText comment)
        {
            // get the user name from the context.
            string userName = String.Empty;

            if (context.UserIdentity != null)
            {
                userName = context.UserIdentity.DisplayName;
            }

            // get the comment.
            string commentText = String.Empty;

            if (comment != null)
            {
                commentText = comment.Text;
            }

            System.Runtime.InteropServices.ComTypes.FILETIME ftActiveTime;

            // unpack the event id.
            ServiceMessageContext messageContext = new ServiceMessageContext();

            messageContext.NamespaceUris = context.NamespaceUris;
            messageContext.ServerUris    = context.ServerUris;
            messageContext.Factory       = context.EncodeableFactory;

            BinaryDecoder decoder = new BinaryDecoder(eventId, messageContext);

            string source        = decoder.ReadString(null);
            string conditionName = decoder.ReadString(null);

            ftActiveTime.dwHighDateTime = decoder.ReadInt32(null);
            ftActiveTime.dwLowDateTime  = decoder.ReadInt32(null);
            int cookie = decoder.ReadInt32(null);

            decoder.Close();

            string methodName = "IOPCEventServer.AckCondition";

            IntPtr pErrors = IntPtr.Zero;

            try
            {
                IOPCEventServer server = BeginComCall <IOPCEventServer>(methodName, true);

                server.AckCondition(
                    1,
                    userName,
                    commentText,
                    new string[] { source },
                    new string[] { conditionName },
                    new System.Runtime.InteropServices.ComTypes.FILETIME[] { ftActiveTime },
                    new int[] { cookie },
                    out pErrors);
            }
            catch (Exception e)
            {
                ComCallError(methodName, e);
                return(StatusCodes.BadUnexpectedError);
            }
            finally
            {
                EndComCall(methodName);
            }

            // unmarshal results.
            int[] errors = ComUtils.GetInt32s(ref pErrors, 1, true);

            if (errors[0] == ResultIds.S_ALREADYACKED)
            {
                return(StatusCodes.BadConditionBranchAlreadyAcked);
            }
            else if (errors[0] < 0)
            {
                return(StatusCodes.BadEventIdUnknown);
            }

            return(StatusCodes.Good);
        }