/// <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)); }
/// <summary> /// Decode Group Message Header /// </summary> /// <param name="decoder"></param> private void DecodeGroupMessageHeader(BinaryDecoder decoder) { // Decode GroupHeader (that holds GroupFlags) if ((UADPFlags & UADPFlagsEncodingMask.GroupHeader) != 0) { GroupFlags = (GroupFlagsEncodingMask)decoder.ReadByte("GroupFlags"); } // Decode WriterGroupId if ((GroupFlags & GroupFlagsEncodingMask.WriterGroupId) != 0) { WriterGroupId = decoder.ReadUInt16("WriterGroupId"); } // Decode GroupVersion if ((GroupFlags & GroupFlagsEncodingMask.GroupVersion) != 0) { GroupVersion = decoder.ReadUInt32("GroupVersion"); } // Decode NetworkMessageNumber if ((GroupFlags & GroupFlagsEncodingMask.NetworkMessageNumber) != 0) { NetworkMessageNumber = decoder.ReadUInt16("NetworkMessageNumber"); } // Decode SequenceNumber if ((GroupFlags & GroupFlagsEncodingMask.SequenceNumber) != 0) { SequenceNumber = decoder.ReadUInt16("SequenceNumber"); } }
/// <summary> /// Decode security header /// </summary> /// <param name="decoder"></param> private void DecodeSecurityHeader(BinaryDecoder decoder) { if ((ExtendedFlags1 & ExtendedFlags1EncodingMask.Security) != 0) { SecurityFlags = (SecurityFlagsEncodingMask)decoder.ReadByte("SecurityFlags"); SecurityTokenId = decoder.ReadUInt32("SecurityTokenId"); NonceLength = decoder.ReadByte("NonceLength"); MessageNonce = decoder.ReadByteArray("MessageNonce").ToArray(); if ((SecurityFlags & SecurityFlagsEncodingMask.SecurityFooter) != 0) { SecurityFooterSize = decoder.ReadUInt16("SecurityFooterSize"); } } }
/// <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.EventNotifier) != 0) { m_eventNotifier = decoder.ReadByte(null); } }
/// <summary> /// Decode Payload Header /// </summary> /// <param name="decoder"></param> private void DecodePayloadHeader(BinaryDecoder decoder) { // Decode PayloadHeader if ((UADPFlags & UADPFlagsEncodingMask.PayloadHeader) != 0) { byte count = decoder.ReadByte("Count"); for (int idx = 0; idx < count; idx++) { m_uaDataSetMessages.Add(new UadpDataSetMessage()); } // collect DataSetSetMessages headers foreach (UadpDataSetMessage uadpDataSetMessage in DataSetMessages) { uadpDataSetMessage.DataSetWriterId = decoder.ReadUInt16("DataSetWriterId"); } } }
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); }
/// <summary> /// Encode Network Message Header /// </summary> /// <param name="decoder"></param> private void DecodeNetworkMessageHeader(BinaryDecoder decoder) { // byte[0..3] UADPVersion value 1 (for now) // byte[4..7] UADPFlags byte versionFlags = decoder.ReadByte("VersionFlags"); UADPVersion = (byte)(versionFlags & kUADPVersionBitMask); // Decode UADPFlags UADPFlags = (UADPFlagsEncodingMask)(versionFlags & 0xF0); // Decode the ExtendedFlags1 if ((UADPFlags & UADPFlagsEncodingMask.ExtendedFlags1) != 0) { ExtendedFlags1 = (ExtendedFlags1EncodingMask)decoder.ReadByte("ExtendedFlags1"); } // Decode the ExtendedFlags2 if ((ExtendedFlags1 & ExtendedFlags1EncodingMask.ExtendedFlags2) != 0) { ExtendedFlags2 = (ExtendedFlags2EncodingMask)decoder.ReadByte("ExtendedFlags2"); } // calculate UADPNetworkMessageType if ((ExtendedFlags2 & ExtendedFlags2EncodingMask.NetworkMessageWithDiscoveryRequest) != 0) { m_uadpNetworkMessageType = UADPNetworkMessageType.DiscoveryRequest; } else if ((ExtendedFlags2 & ExtendedFlags2EncodingMask.NetworkMessageWithDiscoveryResponse) != 0) { m_uadpNetworkMessageType = UADPNetworkMessageType.DiscoveryResponse; } else { m_uadpNetworkMessageType = UADPNetworkMessageType.DataSetMessage; } // Decode PublisherId if ((UADPFlags & UADPFlagsEncodingMask.PublisherId) != 0) { PublisherIdTypeEncodingMask publishedIdTypeType = (PublisherIdTypeEncodingMask)((byte)ExtendedFlags1 & kPublishedIdTypeUsedBits); switch (publishedIdTypeType) { case PublisherIdTypeEncodingMask.UInt16: m_publisherId = decoder.ReadUInt16("PublisherId"); break; case PublisherIdTypeEncodingMask.UInt32: m_publisherId = decoder.ReadUInt32("PublisherId"); break; case PublisherIdTypeEncodingMask.UInt64: m_publisherId = decoder.ReadUInt64("PublisherId"); break; case PublisherIdTypeEncodingMask.String: m_publisherId = decoder.ReadString("PublisherId"); break; case PublisherIdTypeEncodingMask.Byte: default: // 000 The PublisherId is of DataType Byte // This is the default value if ExtendedFlags1 is omitted m_publisherId = decoder.ReadByte("PublisherId"); break; } } // Decode DataSetClassId if ((ExtendedFlags1 & ExtendedFlags1EncodingMask.DataSetClassId) != 0) { DataSetClassId = decoder.ReadGuid("DataSetClassId"); } }
/// <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); } }