public override void ParsePayload (byte[] payloadData, FrameHeader frameHeader) { EndHeaders = (frameHeader.Flags & 0x4) == 0x4; HeaderBlockFragment = new byte[payloadData.Length]; payloadData.CopyTo (HeaderBlockFragment, 0); }
public async Task StartDeviceDiscoveryAsync(CancellationToken cancellationToken) { _listeningClient = new UdpClient(56700); _listeningClient.Client.Blocking = false; _listeningClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); var _ = Task.Factory.StartNew(() => Receive(cancellationToken)); var source = (uint) _randomizer.Next(int.MaxValue); var header = new FrameHeader { Identifier = source }; while (!cancellationToken.IsCancellationRequested) { try { await BroadcastMessageAsync(null, header, MessageType.DeviceGetService, null); } catch { } await Task.Delay(TimeSpan.FromMinutes(5), cancellationToken).ContinueWith(t => { }); } }
/// <summary> /// Sets the label on the device /// </summary> /// <param name="device"></param> /// <param name="label"></param> /// <returns></returns> public async Task SetDeviceLabelAsync(Device device, string label) { FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; var resp = await BroadcastMessageAsync<AcknowledgementResponse>( device.HostName, header, MessageType.DeviceSetLabel, label); }
/// <summary> /// Gets the label for the device /// </summary> /// <param name="device"></param> /// <returns></returns> public async Task<string> GetDeviceLabelAsync(Device device) { FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = false }; var resp = await BroadcastMessageAsync<StateLabelResponse>(device.HostName, header, MessageType.DeviceGetLabel); return resp.Label; }
/// <summary> /// Gets the current power state for a light bulb /// </summary> /// <param name="bulb"></param> /// <returns></returns> public async Task<bool> GetLightPowerAsync(LightBulb bulb) { FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; return (await BroadcastMessageAsync<LightPowerResponse>( bulb.HostName, header, MessageType.LightGetPower).ConfigureAwait(false)).IsOn; }
/// <summary> /// Sets the device power state /// </summary> /// <param name="device"></param> /// <param name="isOn"></param> /// <returns></returns> public async Task SetDevicePowerStateAsync(Device device, bool isOn) { System.Diagnostics.Debug.WriteLine("Sending TurnDeviceOff to {0}", device.HostName); FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; await BroadcastMessageAsync<AcknowledgementResponse>(device.HostName, header, MessageType.DeviceSetPower, (UInt16)(isOn ? 65535 : 0)); }
public void Ctor_TraceFlagSet_BytesReadFromFrame() { // Arrange var header = new FrameHeader { Flags = FrameHeader.HeaderFlag.Tracing }; var body = new MemoryStream(new byte[20]); var frame = new ResponseFrame(header, body); // Act new AbstractResponse(frame); // Assert Assert.AreEqual(16, body.Position); Assert.AreEqual(20, body.Length); }
public override void WriteHeader(System.IO.Stream stream, FrameHeader frameHeader) { string frameID=frameHeader.FrameID; stream.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(frameID), 0, 3); int size=frameHeader.Length; byte[] sizeData=new byte[3]; sizeData[2]=(byte)(size%0x100); size/=0x100; sizeData[1]=(byte)(size%0x100); size/=0x100; sizeData[0]=(byte)(size%0x100); stream.Write(sizeData, 0, 3); }
public void Ctor_TraceFlagSet_TraceIdIsSet() { // Arrange var header = new FrameHeader {Flags = FrameHeader.HeaderFlag.Tracing}; var rnd = new Random(); var buffer = new byte[16]; rnd.NextBytes(buffer); var expected = new Guid(TypeCodec.GuidShuffle(buffer)); var body = new MemoryStream(buffer); var frame = new ResponseFrame(header, body); // Act var uut = new AbstractResponse(frame); // Assert Assert.AreEqual(expected, uut.TraceId); }
private async Task SetLightPowerAsync(LightBulb bulb, TimeSpan transitionDuration, bool isOn) { if (bulb == null) throw new ArgumentNullException("bulb"); if (transitionDuration.TotalMilliseconds > UInt32.MaxValue || transitionDuration.Ticks < 0) throw new ArgumentOutOfRangeException("transitionDuration"); FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; var b = BitConverter.GetBytes((UInt16)transitionDuration.TotalMilliseconds); await BroadcastMessageAsync<AcknowledgementResponse>(bulb.HostName, header, MessageType.LightSetPower, (UInt16)(isOn ? 65535 : 0), b ).ConfigureAwait(false); }
public void Broadcast(int payloadType, byte[] payload) { if (payload.Length > OVRNetwork.MaxPayloadLength) { Debug.LogWarningFormat("[OVRNetworkTcpServer] drop payload because it's too long: {0} bytes", payload.Length); } FrameHeader header = new FrameHeader(); header.protocolIdentifier = FrameHeaderMagicIdentifier; header.payloadType = payloadType; header.payloadLength = payload.Length; byte[] headerBuffer = header.ToBytes(); byte[] dataBuffer = new byte[headerBuffer.Length + payload.Length]; headerBuffer.CopyTo(dataBuffer, 0); payload.CopyTo(dataBuffer, headerBuffer.Length); lock (clientsLock) { foreach (TcpClient client in clients) { if (client.Connected) { try { client.GetStream().BeginWrite(dataBuffer, 0, dataBuffer.Length, new AsyncCallback(DoWriteDataCallback), client.GetStream()); } catch (SocketException e) { Debug.LogWarningFormat("[OVRNetworkTcpServer] close client because of socket error: {0}", e.Message); client.GetStream().Close(); client.Close(); } } } } }
public void FrameHeader_ReadWriteFrameHeader_SucceedOnEmptyExtendedHeader() { // Arrange FrameHeader frameHeader = new FrameHeader(FrameType.MessageJSON, payloadSize: 20, extendedHeaderSize: 0, extendedHeader: null); using (MemoryStream memoryStream = new MemoryStream()) using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream)) { // Action FrameHeader.WriteFrameHeader(frameHeader, binaryWriter); binaryWriter.Flush(); binaryWriter.Seek(0, SeekOrigin.Begin); FrameHeader parsedFrameHeader = FrameHeader.ReadFrameHeader(memoryStream); // Assert Assert.AreEqual(FrameType.MessageJSON, parsedFrameHeader.Type); Assert.AreEqual((ulong)20, parsedFrameHeader.PayloadSize); Assert.AreEqual((uint)0, parsedFrameHeader.ExtendedHeaderSize); Assert.IsNull(parsedFrameHeader.ExtendedHeader); } }
public override void WriteHeader(System.IO.Stream stream, FrameHeader frameHeader) { // Frame ID $xx xx xx xx (four characters) // Size $xx xx xx xx // Flags $xx xx string frameID=frameHeader.FrameID; stream.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(frameID), 0, 4); int size=frameHeader.Length; byte[] sizeData=new byte[4]; sizeData[3]=(byte)(size%0x100); size/=0x100; sizeData[2]=(byte)(size%0x100); size/=0x100; sizeData[1]=(byte)(size%0x100); size/=0x100; sizeData[0]=(byte)(size%0x100); stream.Write(sizeData, 0, 4); stream.WriteByte(0); // Flags stream.WriteByte(0); // Flags }
private void BorderlessEntry_Unfocused(object sender, FocusEventArgs e) { IsHeaderVisible = HeaderShouldBeDisplayed && !string.IsNullOrEmpty((sender as Entry)?.Text); InternalPlaceholder = IsHeaderVisible ? string.Empty : Placeholder; InternalBorderColor = BorderColor; if (!IsHeaderVisible) { Device.BeginInvokeOnMainThread(async() => { await FrameHeader.FadeTo(0, length: 100); }); } if (Text != null && UnfocusValidation) { if (Text.Validations?.Any() == true) { Text.Validate(); } } }
/// <summary> /// Parse the header from the input stream. /// /// This will read bytes up to the start of the data block. /// </summary> /// <param name="input"></param> /// <returns></returns> public static FrameHeader Parse(Stream input) { byte[] buffer = new byte[MaxHeaderSize]; // Read the header if (!WebSocket.ReadBytes(input, buffer, 0, 2)) return null; // Decode it FrameHeader header = new FrameHeader(); header.Finished = ((buffer[0] & 0x80) == 0x80); header.OpCode = (byte)(buffer[0] & 0x0f); header.Masked = ((buffer[1] & 0x80) == 0x80); // Get the length long length = (long)(buffer[1] & 0x7f); // Check for extended length if (length == 126) { // 16 bit payload length if (!WebSocket.ReadBytes(input, buffer, 0, 2)) return null; length = ConvertBytes(buffer, 2); } else if (length == 127) { // 64 bit payload length if (!ReadBytes(input, buffer, 0, 8)) return null; length = ConvertBytes(buffer, 8); } header.Length = length; // If the frame is masked we need the key if (header.Masked) { header.Key = new byte[KeySize]; if (!WebSocket.ReadBytes(input, header.Key, 0, KeySize)) return null; } return header; }
public void OperationStateAppendsBuffers() { var readBuffer = new byte[256]; var writeBuffer = new byte[256]; for (byte i = 1; i < 255; i++) { writeBuffer[i] = i; } var header = new FrameHeader { //256 bytes Len = new byte[] { 0, 0, 1, 0} }; var operationState = new OperationState(); operationState.Header = header; operationState.AppendBody(writeBuffer, 0, 256); operationState.BodyStream.Position = 0; operationState.BodyStream.Read(readBuffer, 0, 256); Assert.AreEqual(writeBuffer, readBuffer); operationState = new OperationState(); operationState.Header = header; operationState.AppendBody(writeBuffer, 0, 100); operationState.AppendBody(writeBuffer, 100, 100); operationState.AppendBody(writeBuffer, 200, 50); operationState.AppendBody(writeBuffer, 250, 6); operationState.BodyStream.Position = 0; operationState.BodyStream.Read(readBuffer, 0, 256); Assert.AreEqual(writeBuffer, readBuffer); operationState.BodyStream.Position = 0; operationState.BodyStream.Read(readBuffer, 0, 128); operationState.BodyStream.Read(readBuffer, 128, 128); Assert.AreEqual(writeBuffer, readBuffer); }
public void GetRequest_Batch_With_Provided_Timestamp() { var batch = new BatchStatement(); batch.Add(new SimpleStatement("QUERY")); var providedTimestamp = DateTimeOffset.Now; // To microsecond precision providedTimestamp = providedTimestamp.Subtract(TimeSpan.FromTicks(providedTimestamp.Ticks % 10)); batch.SetTimestamp(providedTimestamp); var config = new Configuration( Policies.DefaultPolicies, new ProtocolOptions(), PoolingOptions.Create(), new SocketOptions(), new ClientOptions(), NoneAuthProvider.Instance, null, new QueryOptions(), new DefaultAddressTranslator()); var request = RequestHandler.GetRequest(batch, Serializer, config); var stream = new MemoryStream(); request.WriteFrame(1, stream, Serializer); var headerSize = FrameHeader.GetSize(ProtocolVersion.MaxSupported); var bodyBuffer = new byte[stream.Length - headerSize]; stream.Position = headerSize; stream.Read(bodyBuffer, 0, bodyBuffer.Length); // The batch request is composed by: // <type><n><query_1>...<query_n><consistency><flags>[<serial_consistency>][<timestamp>] var offset = 1 + 2 + 1; var queryLength = BeConverter.ToInt32(bodyBuffer, offset); Assert.AreEqual(5, queryLength); // skip query, n_params and consistency offset += 4 + queryLength + 2 + 2; var flags = (QueryFlags)bodyBuffer[offset++]; Assert.True(flags.HasFlag(QueryFlags.WithDefaultTimestamp)); var timestamp = TypeSerializer.UnixStart.AddTicks(BeConverter.ToInt64(bodyBuffer, offset) * 10); Assert.AreEqual(providedTimestamp, timestamp); }
/// <summary> /// Returns an action that capture the parameters closure /// </summary> private Action <MemoryStream> CreateResponseAction(FrameHeader header, Action <Exception, Response> callback) { var compressor = Compressor; void DeserializeResponseStream(MemoryStream stream) { Response response = null; Exception ex = null; var nextPosition = stream.Position + header.BodyLength; try { Stream plainTextStream = stream; if (header.Flags.HasFlag(FrameHeader.HeaderFlag.Compression)) { plainTextStream = compressor.Decompress(new WrappedStream(stream, header.BodyLength)); plainTextStream.Position = 0; } response = FrameParser.Parse(new Frame(header, plainTextStream, _serializer)); } catch (Exception catchedException) { ex = catchedException; } if (response is ErrorResponse) { //Create an exception from the response error ex = ((ErrorResponse)response).Output.CreateException(); response = null; } //We must advance the position of the stream manually in case it was not correctly parsed stream.Position = nextPosition; callback(ex, response); } return(DeserializeResponseStream); }
public async Task ConnectionShouldGoAwayOnInvalidGoAwayStreamId( bool isServer) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); var goAwayData = new GoAwayFrameData { Reason = new GoAwayReason { LastStreamId = 0u, ErrorCode = ErrorCode.NoError, DebugData = new ArraySegment <byte>(new byte[0]), }, }; var fh = new FrameHeader { Type = FrameType.GoAway, Flags = 0, StreamId = 1, Length = goAwayData.RequiredSize, }; var dataBytes = new byte[goAwayData.RequiredSize]; goAwayData.EncodeInto(new ArraySegment <byte>(dataBytes)); await inPipe.WriteFrameHeader(fh); await inPipe.WriteAsync(new ArraySegment <byte>(dataBytes)); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0); await outPipe.AssertStreamEnd(); }
public async Task ConnectionShouldIgnoreAndAcknowledgeUnknownSettings() { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = BuildConnection(true, Settings.Default, inPipe, outPipe); await ClientPreface.WriteAsync(inPipe); await outPipe.ReadAndDiscardSettings(); var settings = Settings.Default; // Create a buffer for normal settings plus 3 unknown ones var settingsBuffer = new byte[settings.RequiredSize + 18]; settings.EncodeInto(new ArraySegment <byte>( settingsBuffer, 0, settings.RequiredSize)); // Use some unknown settings IDs settingsBuffer[settings.RequiredSize] = 0; settingsBuffer[settings.RequiredSize + 1] = 10; settingsBuffer[settings.RequiredSize + 6] = 10; settingsBuffer[settings.RequiredSize + 7] = 20; settingsBuffer[settings.RequiredSize + 12] = 0xFF; settingsBuffer[settings.RequiredSize + 13] = 0xFF; var settingsHeader = new FrameHeader { Type = FrameType.Settings, StreamId = 0, Flags = 0, Length = settingsBuffer.Length, }; await inPipe.WriteFrameHeader(settingsHeader); await inPipe.WriteAsync(new ArraySegment <byte>(settingsBuffer)); // Check if the connection ACKs these settings await outPipe.AssertSettingsAck(); }
/// <summary> /// Returns an action that capture the parameters closure /// </summary> private Action <MemoryStream, long> CreateResponseAction( ResultMetadata resultMetadata, ISerializer serializer, FrameHeader header, Action <IRequestError, Response, long> callback) { var compressor = Compressor; void DeserializeResponseStream(MemoryStream stream, long timestamp) { Response response = null; IRequestError error = null; var nextPosition = stream.Position + header.BodyLength; try { Stream plainTextStream = stream; if (header.Flags.HasFlag(HeaderFlags.Compression)) { plainTextStream = compressor.Decompress(new WrappedStream(stream, header.BodyLength)); plainTextStream.Position = 0; } response = FrameParser.Parse(new Frame(header, plainTextStream, serializer, resultMetadata)); } catch (Exception caughtException) { error = RequestError.CreateClientError(caughtException, false); } if (response is ErrorResponse errorResponse) { error = RequestError.CreateServerError(errorResponse); response = null; } //We must advance the position of the stream manually in case it was not correctly parsed stream.Position = nextPosition; callback(error, response, timestamp); } return(DeserializeResponseStream); }
/// <summary> /// Read data from the input stream into the frame buffer /// </summary> /// <param name="header"></param> /// <param name="buffer"></param> /// <param name="offset"></param> /// <returns></returns> private bool ReadData(FrameHeader header, byte[] buffer, int offset) { // Would this overflow the buffer? long total = header.Length + (long)offset; if (total >= MaxFrameSize) { return(ConsumeData(header)); } // Read into the buffer if (!ReadBytes(m_input, buffer, offset, (int)header.Length)) { return(false); } // Do we need to unmask the data ? if (header.Masked) { for (int i = 0; i < (int)header.Length; i++) { buffer[offset + i] = (byte)(buffer[offset + i] ^ header.Key[i % 4]); } } return(true); }
private async ValueTask <object> SendWindowUpdate(int amount) { var fh = new FrameHeader { StreamId = this.Id, Type = FrameType.WindowUpdate, Flags = 0, }; var updateData = new WindowUpdateData { WindowSizeIncrement = amount, }; try { await this.connection.writer.WriteWindowUpdate(fh, updateData); } catch (Exception) { } return(null); }
public async Task InvalidContinuationFramesShouldLeadToGoAway( uint contStreamId, int?contLength, FrameType contFrameType) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); Func <IStream, bool> listener = (s) => true; var http2Con = await ConnectionUtils.BuildEstablishedConnection( true, inPipe, outPipe, loggerProvider, listener); var hEncoder = new Encoder(); // Send a valid HEADERS frame await inPipe.WriteHeaders( hEncoder, 1, false, DefaultGetHeaders.Take(2), false); // Followed by an invalid continuation frame var outBuf = new byte[Settings.Default.MaxFrameSize]; var result = hEncoder.EncodeInto( new ArraySegment <byte>(outBuf), DefaultGetHeaders.Skip(2)); var length = contLength ?? result.UsedBytes; var fh = new FrameHeader { Type = contFrameType, StreamId = contStreamId, Length = length, Flags = 0, }; await inPipe.WriteFrameHeader(fh); await outPipe.AssertGoAwayReception(ErrorCode.ProtocolError, 0u); await outPipe.AssertStreamEnd(); }
public override void WriteHeader(System.IO.Stream stream, FrameHeader frameHeader) { // Frame ID $xx xx xx xx (four characters) // Size 4 * %0xxxxxxx // Flags $xx xx string frameID = frameHeader.FrameID; stream.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(frameID), 0, 4); int size = frameHeader.Length; byte[] sizeData = new byte[4]; sizeData[3] = (byte)(size % 0x80); size /= 0x80; sizeData[2] = (byte)(size % 0x80); size /= 0x80; sizeData[1] = (byte)(size % 0x80); size /= 0x80; sizeData[0] = (byte)(size % 0x80); stream.Write(sizeData, 0, 4); stream.WriteByte(0); // Flags stream.WriteByte(0); // Flags }
public static async Task WriteGoAway( this IWriteAndCloseableByteStream stream, uint lastStreamId, ErrorCode errc, byte[] debugData = null) { if (debugData == null) { debugData = new byte[0]; } var goAwayData = new GoAwayFrameData { Reason = new GoAwayReason { LastStreamId = lastStreamId, ErrorCode = errc, DebugData = new ArraySegment <byte>(debugData), }, }; var fh = new FrameHeader { Type = FrameType.GoAway, Flags = 0, StreamId = 0, Length = goAwayData.RequiredSize, }; var dataBytes = new byte[goAwayData.RequiredSize]; goAwayData.EncodeInto(new ArraySegment <byte>(dataBytes)); await stream.WriteFrameHeader(fh); await stream.WriteAsync(new ArraySegment <byte>(dataBytes)); }
public async Task ConnectionShouldIgnoreUnknownFrames( bool isServer, int payloadLength) { var inPipe = new BufferedPipe(1024); var outPipe = new BufferedPipe(1024); var http2Con = await ConnectionUtils.BuildEstablishedConnection( isServer, inPipe, outPipe, loggerProvider); // send an undefined frame type var fh = new FrameHeader { Type = (FrameType)100, Flags = 33, Length = payloadLength, StreamId = 0, }; await inPipe.WriteFrameHeader(fh); if (payloadLength != 0) { var payload = new byte[payloadLength]; await inPipe.WriteAsync(new ArraySegment <byte>(payload)); } // Send a ping afterwards // If we get a response the unknown frame in between was ignored var pingData = new byte[8]; for (var i = 0; i < 8; i++) { pingData[i] = (byte)i; } await inPipe.WritePing(pingData, false); await outPipe.ReadAndDiscardPong(); }
public ControlButton(ushort x, ushort y, uint resId, ButtonIds id, byte flag, ResMan pResMan, byte[] screenBuf, ISystem system) { _x = x; _y = y; _id = id; _flag = flag; _resId = resId; _resMan = pResMan; _frameIdx = 0; _resMan.ResOpen(_resId); FrameHeader tmp = new FrameHeader(_resMan.FetchFrame(_resMan.FetchRes(_resId), 0)); _width = _resMan.ReadUInt16(tmp.width); _width = (ushort)((_width > Screen.SCREEN_WIDTH) ? Screen.SCREEN_WIDTH : _width); _height = _resMan.ReadUInt16(tmp.height); if ((x == 0) && (y == 0)) { // center the frame (used for panels); _x = (ushort)((((640 - _width) / 2) < 0) ? 0 : ((640 - _width) / 2)); _y = (ushort)((((480 - _height) / 2) < 0) ? 0 : ((480 - _height) / 2)); } _dstBuf = new ByteAccess(screenBuf, _y * Screen.SCREEN_WIDTH + _x); _system = system; }
public void GetRequest_Batch_With_64K_Queries() { var batch = new BatchStatement(); for (var i = 0; i < ushort.MaxValue; i++) { batch.Add(new SimpleStatement("QUERY")); } var config = new Configuration( Policies.DefaultPolicies, new ProtocolOptions(), PoolingOptions.Create(), new SocketOptions(), new ClientOptions(), NoneAuthProvider.Instance, null, new QueryOptions(), new DefaultAddressTranslator()); var request = RequestHandler.GetRequest(batch, Serializer, config); var stream = new MemoryStream(); request.WriteFrame(1, stream, Serializer); var headerSize = FrameHeader.GetSize(ProtocolVersion.MaxSupported); var bodyBuffer = new byte[stream.Length - headerSize]; stream.Position = headerSize; stream.Read(bodyBuffer, 0, bodyBuffer.Length); // The batch request is composed by: // <type><n><query_1>...<query_n><consistency><flags>[<serial_consistency>][<timestamp>] CollectionAssert.AreEqual(new byte[] { 0xff, 0xff }, bodyBuffer.Skip(1).Take(2)); }
internal static LifxResponse Create(FrameHeader header, MessageType type, UInt32 source, byte[] payload) { LifxResponse response = null; switch(type) { case MessageType.DeviceAcknowledgement: response = new AcknowledgementResponse(payload); break; case MessageType.DeviceStateLabel: response = new StateLabelResponse(payload); break; case MessageType.LightState: response = new LightStateResponse(payload); break; case MessageType.LightStatePower: response = new LightPowerResponse(payload); break; case MessageType.DeviceStateVersion: response = new StateVersionResponse(payload); break; case MessageType.DeviceStateHostFirmware: response = new StateHostFirmwareResponse(payload); break; case MessageType.DeviceStateService: response = new StateServiceResponse(payload); break; default: response = new UnknownResponse(payload); break; } response.Header = header; response.Type = type; response.Payload = payload; response.Source = source; return response; }
public async Task SetupAsync() { // Send connection preface _outgoingBuffer.EnsureAvailableSpace(s_http2ConnectionPreface.Length); s_http2ConnectionPreface.AsSpan().CopyTo(_outgoingBuffer.AvailableSpan); _outgoingBuffer.Commit(s_http2ConnectionPreface.Length); // Send empty settings frame _outgoingBuffer.EnsureAvailableSpace(FrameHeader.Size); WriteFrameHeader(new FrameHeader(0, FrameType.Settings, FrameFlags.None, 0)); // TODO: ISSUE 31295: We should disable PUSH_PROMISE here. // TODO: ISSUE 31298: We should send a connection-level WINDOW_UPDATE to allow // a large amount of data to be received on the connection. // We don't care that much about connection-level flow control, we'll manage it per-stream. await _stream.WriteAsync(_outgoingBuffer.ActiveMemory).ConfigureAwait(false); _outgoingBuffer.Discard(_outgoingBuffer.ActiveMemory.Length); _expectingSettingsAck = true; // Receive the initial SETTINGS frame from the peer. FrameHeader frameHeader = await ReadFrameAsync().ConfigureAwait(false); if (frameHeader.Type != FrameType.Settings || frameHeader.AckFlag) { throw new Http2ProtocolException(Http2ProtocolErrorCode.ProtocolError); } // Process the SETTINGS frame. This will send an ACK. ProcessSettingsFrame(frameHeader); ProcessIncomingFrames(); }
/// <summary> /// Saves the current read state (header and body stream) for the next read event. /// </summary> private void StoreReadState(FrameHeader header, MemoryStream stream, byte[] buffer, int offset, int length, bool hasReadFromStream) { MemoryStream nextMessageStream; if (!hasReadFromStream && stream != null) { // There hasn't been any operations completed with this buffer, reuse the current stream nextMessageStream = stream; } else { // Allocate a new stream for store in it nextMessageStream = Configuration.BufferPool.GetStream(Connection.StreamReadTag); } nextMessageStream.Write(buffer, offset, length - offset); Volatile.Write(ref _readStream, nextMessageStream); Volatile.Write(ref _receivingHeader, header); if (_isCanceled) { // Connection was disposed since we started to store the buffer, try to dispose the stream Interlocked.Exchange(ref _readStream, null)?.Dispose(); } }
private void ProcessWindowUpdateFrame(FrameHeader frameHeader) { Debug.Assert(frameHeader.Type == FrameType.WindowUpdate); if (frameHeader.Length != FrameHeader.WindowUpdateLength) { throw new Http2ProtocolException(Http2ProtocolErrorCode.FrameSizeError); } int amount = BinaryPrimitives.ReadInt32BigEndian(_incomingBuffer.ActiveSpan) & 0x7FFFFFFF; Debug.Assert(amount >= 0); if (amount == 0) { throw new Http2ProtocolException(Http2ProtocolErrorCode.ProtocolError); } _incomingBuffer.Discard(frameHeader.Length); if (frameHeader.StreamId == 0) { _connectionWindow.AdjustCredit(amount); } else { Http2Stream http2Stream = GetStream(frameHeader.StreamId); if (http2Stream == null) { // Don't wait for completion, which could happen asynchronously. Task ignored = SendRstStreamAsync(frameHeader.StreamId, Http2ProtocolErrorCode.StreamClosed); return; } http2Stream.OnWindowUpdate(amount); } }
private async ValueTask <FlushResult> OnContent(FrameHeader header, CancellationToken cancellationToken) { Channel channel; lock (this.syncObject) { channel = this.openChannels[header.ChannelId]; } // Read directly from the transport stream to memory that the targeted channel's reader will read from for 0 extra buffer copies. PipeWriter writer = channel.ReceivedMessagePipeWriter; Memory <byte> memory = writer.GetMemory(header.FramePayloadLength); var payload = memory.Slice(0, header.FramePayloadLength); await ReadToFillAsync(this.stream, payload, throwOnEmpty : true, cancellationToken).ConfigureAwait(false); if (!payload.IsEmpty && this.TraceSource.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceData(TraceEventType.Verbose, (int)TraceEventId.FrameReceivedPayload, payload); } writer.Advance(header.FramePayloadLength); return(await writer.FlushAsync(cancellationToken).ConfigureAwait(false)); }
private static byte getVBRDeviation(FrameHeader Frame) { // Calculate VBR deviation if (MPEG_VERSION_1 == Frame.VersionID) { if (Frame.ModeID != MPEG_CM_MONO) { return(36); } else { return(21); } } else if (Frame.ModeID != MPEG_CM_MONO) { return(21); } else { return(13); } }
protected Frame(FrameHeader header) { Header = header; }
public Popularimeter(FrameHeader header) : base(header) { }
ThreadData GenerateSamplingThread(FrameGroup group, ThreadData thread) { List <Entry> entries = new List <Entry>(); List <Entry> stack = new List <Entry>(); List <EventFrame> frames = new List <EventFrame>(); Callstack current = new Callstack(); for (int csIndex = 0; csIndex < thread.Callstacks.Count; ++csIndex) { Callstack callstack = thread.Callstacks[csIndex]; if (current.Start == callstack.Start) { continue; } int matchCount = 0; for (int i = 0; i < Math.Min(current.Count, callstack.Count); ++i, ++matchCount) { if (current[i].Name != callstack[i].Name) { break; } } for (int i = matchCount; i < stack.Count; ++i) { stack[i].Finish = callstack.Start; } stack.RemoveRange(matchCount, stack.Count - matchCount); if (stack.Count == 0 && matchCount > 0) { FrameHeader h = new FrameHeader() { Start = entries.Min(e => e.Start), Finish = entries.Max(e => e.Finish), }; frames.Add(new EventFrame(h, entries, group)); entries.Clear(); } for (int i = matchCount; i < callstack.Count; ++i) { Entry entry = new Entry(new EventDescription(callstack[i].Name), callstack.Start, long.MaxValue); entries.Add(entry); stack.Add(entry); } current = callstack; } foreach (Entry e in stack) { e.Finish = current.Start; } FrameHeader header = new FrameHeader() { Start = thread.Callstacks.First().Start, Finish = thread.Callstacks.Last().Start, }; frames.Add(new EventFrame(header, entries, group)); ThreadData result = new ThreadData(null) { Events = frames }; return(result); }
/// <summary> /// Returns an action that capture the parameters closure /// </summary> private Action<MemoryStream> CreateResponseAction(FrameHeader header, Action<Exception, Response> callback) { var compressor = Compressor; var bufferPool = Configuration.BufferPool; var decompressorBuffer = _decompressorBuffer; return stream => { Response response = null; Exception ex = null; var nextPosition = stream.Position + header.BodyLength; try { Stream plainTextStream = stream; if (header.Flags.HasFlag(FrameHeader.HeaderFlag.Compression)) { var compressedBodyStream = bufferPool.GetStream(typeof (Connection) + "/Decompress", header.BodyLength); Utils.CopyStream(stream, compressedBodyStream, header.BodyLength, decompressorBuffer); compressedBodyStream.Position = 0; plainTextStream = compressor.Decompress(compressedBodyStream); plainTextStream.Position = 0; } response = FrameParser.Parse(new Frame(header, plainTextStream)); } catch (Exception catchedException) { ex = catchedException; } if (response is ErrorResponse) { //Create an exception from the response error ex = ((ErrorResponse)response).Output.CreateException(); response = null; } //We must advance the position of the stream manually in case it was not correctly parsed stream.Position = nextPosition; callback(ex, response); }; }
public TermsOfUseFrame(FrameHeader header) : base(header) { }
private static void readFrameHeader(byte[] pData, ref int p, ref FrameHeader header) { int pos = p; readUShort(pData, ref pos); header.nSamplePrecision = readByte(pData, ref pos); header.nHeight = readUShort(pData, ref pos); header.nWidth = readUShort(pData, ref pos); header.nComponents = readByte(pData, ref pos); for (int c = 0; c < header.nComponents; ++c) { header.aComponentIdentifier[c] = readByte(pData, ref pos); header.aSamplingFactors[c] = readByte(pData, ref pos); header.aQuantizationTableSelector[c] = readByte(pData, ref pos); } }
/// <summary> /// Constructs and initializes a new instance of <see /// cref="PopularimeterFrame" /> by reading its raw data in a /// specified ID3v2 version. /// </summary> /// <param name="data"> /// A <see cref="ByteVector" /> object containing the raw /// representation of the new frame. /// </param> /// <param name="offset"> /// A <see cref="int" /> indicating at what offset in /// <paramref name="data" /> the frame actually begins. /// </param> /// <param name="header"> /// A <see cref="FrameHeader" /> containing the header of the /// frame found at <paramref name="offset" /> in the data. /// </param> /// <param name="version"> /// A <see cref="byte" /> indicating the ID3v2 version the /// raw frame is encoded in. /// </param> protected internal PopularimeterFrame(ByteVector data, int offset, FrameHeader header, byte version) : base(header) { SetData(data, offset, version, false); }
public UnknownMessage(FrameHeader header, MessageType type, Function function, byte[] payload) : base(header, type, function) { Payload = payload; }
private AbstractResponse ReadParseResponse(FrameHeader header, Stream body) { //Start at the first byte body.Position = 0; if ((header.Flags & 0x01) > 0) { body = Compressor.Decompress(body); } var frame = new ResponseFrame(header, body); var response = FrameParser.Parse(frame); return response; }
/// <summary> /// Read data from the input stream into the frame buffer /// </summary> /// <param name="header"></param> /// <param name="buffer"></param> /// <param name="offset"></param> /// <returns></returns> private bool ReadData(FrameHeader header, byte[] buffer, int offset) { // Would this overflow the buffer? long total = header.Length + (long)offset; if (total >= MaxFrameSize) return ConsumeData(header); // Read into the buffer if (!ReadBytes(m_input, buffer, offset, (int)header.Length)) return false; // Do we need to unmask the data ? if (header.Masked) { for(int i=0; i<(int)header.Length; i++) buffer[offset + i] = (byte)(buffer[offset + i] ^ header.Key[i % 4]); } return true; }
/// <summary> /// Read, but do not store, the data from the input stream /// </summary> /// <param name="header"></param> /// <returns></returns> private bool ConsumeData(FrameHeader header) { const int DiscardBufferSize = 128; byte[] buffer = new byte[DiscardBufferSize]; long remaining = header.Length; while (remaining > 0) { if (!ReadBytes(m_input, buffer, 0, Math.Min((int)remaining, DiscardBufferSize))) return false; remaining -= (long)DiscardBufferSize; } return true; }
/* public async Task SetBrightnessAsync(LightBulb bulb, UInt16 brightness, TimeSpan transitionDuration) { if (transitionDuration.TotalMilliseconds > UInt32.MaxValue || transitionDuration.Ticks < 0) throw new ArgumentOutOfRangeException("transitionDuration"); FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; UInt32 duration = (UInt32)transitionDuration.TotalMilliseconds; var durationBytes = BitConverter.GetBytes(duration); var b = BitConverter.GetBytes(brightness); await BroadcastMessageAsync<AcknowledgementResponse>(bulb.HostName, header, MessageType.SetLightBrightness, brightness, duration ); }*/ /// <summary> /// Gets the current state of the bulb /// </summary> /// <param name="bulb"></param> /// <returns></returns> public Task<LightStateResponse> GetLightStateAsync(LightBulb bulb) { FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = false }; return BroadcastMessageAsync<LightStateResponse>( bulb.HostName, header, MessageType.LightGet); }
/// <summary> /// Sets color and temperature for a bulb and uses a transition time to the provided state /// </summary> /// <param name="bulb">Light bulb</param> /// <param name="hue">0..65535</param> /// <param name="saturation">0..65535</param> /// <param name="brightness">0..65535</param> /// <param name="kelvin">2700..9000</param> /// <param name="transitionDuration"></param> /// <returns></returns> public async Task SetColorAsync(LightBulb bulb, UInt16 hue, UInt16 saturation, UInt16 brightness, UInt16 kelvin, TimeSpan transitionDuration) { if (transitionDuration.TotalMilliseconds > UInt32.MaxValue || transitionDuration.Ticks < 0) throw new ArgumentOutOfRangeException("transitionDuration"); if (kelvin < 2500 || kelvin > 9000) { throw new ArgumentOutOfRangeException("kelvin", "Kelvin must be between 2500 and 9000"); } System.Diagnostics.Debug.WriteLine("Setting color to {0}", bulb.HostName); FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = true }; UInt32 duration = (UInt32)transitionDuration.TotalMilliseconds; var durationBytes = BitConverter.GetBytes(duration); var h = BitConverter.GetBytes(hue); var s = BitConverter.GetBytes(saturation); var b = BitConverter.GetBytes(brightness); var k = BitConverter.GetBytes(kelvin); await BroadcastMessageAsync<AcknowledgementResponse>(bulb.HostName, header, MessageType.LightSetColor, (byte)0x00, //reserved hue, saturation, brightness, kelvin, //HSBK duration ); }
private static void writeFrameHeader(FrameHeader header, byte[] pData, ref int pos) { byte[] pTemp = new byte[128]; int posTemp = 0; write(pTemp, header.nSamplePrecision, ref posTemp); write(pTemp, header.nHeight, ref posTemp); write(pTemp, header.nWidth, ref posTemp); write(pTemp, header.nComponents, ref posTemp); for (int c = 0; c < header.nComponents; ++c) { write(pTemp, header.aComponentIdentifier[c], ref posTemp); write(pTemp, header.aSamplingFactors[c], ref posTemp); write(pTemp, header.aQuantizationTableSelector[c], ref posTemp); } ushort nLength = (ushort)(posTemp); writeMarker(0x0C0, pData, ref pos); write(pData, (ushort)(nLength + 2), ref pos); for (int i = 0; i < nLength; i++) { pData[pos + i] = pTemp[i]; } pos += nLength; }
/// <summary> /// Returns an action that capture the parameters closure /// </summary> private Action<MemoryStream> CreateResponseAction(FrameHeader header, Action<Exception, Response> callback) { var compressor = Compressor; return delegate(MemoryStream stream) { Response response = null; Exception ex = null; var nextPosition = stream.Position + header.BodyLength; try { Stream plainTextStream = stream; if (header.Flags.HasFlag(FrameHeader.HeaderFlag.Compression)) { plainTextStream = compressor.Decompress(new WrappedStream(stream, header.BodyLength)); plainTextStream.Position = 0; } response = FrameParser.Parse(new Frame(header, plainTextStream)); } catch (Exception catchedException) { ex = catchedException; } if (response is ErrorResponse) { //Create an exception from the response error ex = ((ErrorResponse) response).Output.CreateException(); response = null; } //We must advance the position of the stream manually in case it was not correctly parsed stream.Position = nextPosition; callback(ex, response); }; }
public UnknownMessage(FrameHeader header, MessageType type, Function function, byte[] payload) : base(header, type, function) { Payload = payload; }
/// <summary> /// Gets the device's host firmware /// </summary> /// <param name="device"></param> /// <returns></returns> public async Task<StateHostFirmwareResponse> GetDeviceHostFirmwareAsync(Device device) { FrameHeader header = new FrameHeader() { Identifier = (uint)randomizer.Next(), AcknowledgeRequired = false }; var resp = await BroadcastMessageAsync<StateHostFirmwareResponse>(device.HostName, header, MessageType.DeviceGetHostFirmware); return resp; }
// Reads next frame into buffer public bool BufferNextFrame(int frameNum = -1) { if (!ReadyToPlay) { Debug.Log("PlayNextFrame() found readyToPlay false; stopping"); return(false); } frameNum = (frameNum >= 0 && frameNum <= header.NumOfFrames) ? frameNum : CurrentFrame; FrameHeader fh = FrameHeaders[frameNum]; reader.BaseStream.Seek(fh.posInFile + FRAMEHEADERSIZE, SeekOrigin.Begin); // Go to frame start, skip over header for (int i = 0; i < fh.numSubChunks; i++) { ChunkHeader ch; if (!ReadChunkHeader(out ch)) { Debug.LogError("Invalid chunk type: " + ch.type); return(false); } else { //Debug.Log("Chunk Type: " + ch.type.ToString()); switch (ch.type) // Daggerfall .flc's only uses Color_256, Delta_FLC, Byte_Run, PSTAMP chunk types { case ChunkType.COLOR_256: Decode_COLOR(); break; case ChunkType.COLOR_64: Decode_COLOR(true); break; case ChunkType.DELTA_FLC: Decode_Delta_FLC(); break; case ChunkType.DELTA_FLI: Decode_Delta_FLI(); break; case ChunkType.BYTE_RUN: Decode_BYTE_RUN(); break; case ChunkType.PSTAMP: // Skip over PSTAMP type - usually first chunk of first frame reader.BaseStream.Seek(ch.size - CHUNKHEADERSIZE, SeekOrigin.Current); break; default: // Skip over unsupported chunk types var skip = reader.BaseStream.Position + ch.size - CHUNKHEADERSIZE; if (skip > header.FileSize) { Debug.LogError("Read error - tried to skip past the end of file"); ReadyToPlay = false; return(false); } else { reader.BaseStream.Seek(skip, SeekOrigin.Current); } break; } } } // Use ++frameNum for next frame if not at last frame; or skip over frame 0 CurrentFrame = (++frameNum <= header.NumOfFrames) ? frameNum : 1; return(true); }
public Frame (FrameHeader header, FrameExtendedHeader extendedHeader, FrameBody body) { Header = header; ExtendedHeader = extendedHeader; Body = body; }
/// <summary> /// Parses the bytes received into a frame. Uses the internal operation state to do the callbacks. /// Returns true if a full operation (streamId) has been processed and there is one available. /// </summary> /// <returns>True if a full operation (streamId) has been processed.</returns> internal bool ReadParse(byte[] buffer, int length) { if (length <= 0) { return false; } if (_frameHeaderSize == 0) { //Read the first byte of the message to determine the version of the response ProtocolVersion = FrameHeader.GetProtocolVersion(buffer); _frameHeaderSize = FrameHeader.GetSize(ProtocolVersion); } //Use _readStream to buffer between messages, under low pressure, it should be null most of the times var stream = Interlocked.Exchange(ref _readStream, null); var operationCallbacks = new LinkedList<Action<MemoryStream>>(); var offset = 0; if (_minimalBuffer != null) { //use a negative offset to identify that there is a previous header buffer offset = -1 * _minimalBuffer.Length; } while (offset < length) { FrameHeader header; //The remaining body length to read from this buffer int remainingBodyLength; if (_receivingHeader == null) { if (length - offset < _frameHeaderSize) { _minimalBuffer = offset >= 0 ? Utils.SliceBuffer(buffer, offset, length - offset) : //it should almost never be the case there isn't enough bytes to read the header more than once // ReSharper disable once PossibleNullReferenceException Utils.JoinBuffers(_minimalBuffer, 0, _minimalBuffer.Length, buffer, 0, length); break; } if (offset >= 0) { header = FrameHeader.ParseResponseHeader(ProtocolVersion, buffer, offset); } else { header = FrameHeader.ParseResponseHeader(ProtocolVersion, _minimalBuffer, buffer); _minimalBuffer = null; } _logger.Verbose("Received #{0} from {1}", header.StreamId, Address); offset += _frameHeaderSize; remainingBodyLength = header.BodyLength; } else { header = _receivingHeader; remainingBodyLength = header.BodyLength - (int) stream.Length; _receivingHeader = null; } if (remainingBodyLength > length - offset) { //the buffer does not contains the body for this frame, buffer for later MemoryStream nextMessageStream; if (operationCallbacks.Count == 0 && stream != null) { //There hasn't been any operations completed with this buffer //And there is a previous stream: reuse it nextMessageStream = stream; } else { nextMessageStream = Configuration.BufferPool.GetStream(typeof(Connection) + "/Read"); } nextMessageStream.Write(buffer, offset, length - offset); Interlocked.Exchange(ref _readStream, nextMessageStream); _receivingHeader = header; break; } stream = stream ?? Configuration.BufferPool.GetStream(typeof (Connection) + "/Read"); OperationState state; if (header.Opcode != EventResponse.OpCode) { state = RemoveFromPending(header.StreamId); } else { //Its an event state = new OperationState(EventHandler); } stream.Write(buffer, offset, remainingBodyLength); var callback = state.SetCompleted(); operationCallbacks.AddLast(CreateResponseAction(header, callback)); offset += remainingBodyLength; } return InvokeReadCallbacks(stream, operationCallbacks); }
/// <summary> /// Initializes a new instance of the <see cref="ZWaveLib.ZWaveMessage"/> class. /// </summary> /// <param name="message">Message.</param> /// <param name="direction">Direction.</param> /// <param name="generateCallback">If set to <c>true</c> generate callback.</param> public ZWaveMessage(byte[] message, MessageDirection direction = MessageDirection.Outbound, bool generateCallback = false) { Direction = direction; Header = (FrameHeader)message[0]; RawData = message; if (direction == MessageDirection.Outbound) { if (generateCallback) { CallbackId = GenerateCallbackId(); RawData[RawData.Length - 2] = CallbackId; } // Insert checksum RawData[RawData.Length - 1] = GenerateChecksum(RawData); } if (Header == FrameHeader.SOF) { if (message.Length > 4) { Enum.TryParse<MessageType>(message[2].ToString(), out Type); Enum.TryParse<ZWaveFunction>(message[3].ToString(), out Function); } switch (Type) { case MessageType.Request: if (Function == ZWaveFunction.SendData && message.Length == 6) { Enum.TryParse<CallbackStatus>(message[4].ToString(), out CallbackStatus); } else if (Function == ZWaveFunction.SendData && (message.Length == 7 || message.Length == 9)) { CallbackId = message[4]; Enum.TryParse<CallbackStatus>(message[5].ToString(), out CallbackStatus); } else if (Function == ZWaveFunction.SendData && message.Length == 8) { Enum.TryParse<CommandClass>(message[6].ToString(), out CommandClass); } else if (Function == ZWaveFunction.SendData && message.Length > 6) { NodeId = message[4]; Enum.TryParse<CommandClass>(message[6].ToString(), out CommandClass); } else if (Function == ZWaveFunction.ApplicationCommandHandler && message.Length > 7) { NodeId = message[5]; Enum.TryParse<CommandClass>(message[7].ToString(), out CommandClass); } else if ((Function == ZWaveFunction.RequestNodeNeighborsUpdate || Function == ZWaveFunction.RequestNodeNeighborsUpdateOptions) && message.Length >= 6) { if (Direction == MessageDirection.Outbound) { NodeId = message[4]; CallbackId = (Function == ZWaveFunction.RequestNodeNeighborsUpdate) ? message[5] : message[6]; } else { CallbackId = message[4]; } } else if ((Function == ZWaveFunction.NodeAdd || Function == ZWaveFunction.NodeRemove) && message.Length == 9) { CallbackId = message[4]; } else if (Function == ZWaveFunction.RequestNodeInfo || Function == ZWaveFunction.GetNodeProtocolInfo || Function == ZWaveFunction.GetRoutingInfo) { NodeId = message[4]; } break; case MessageType.Response: if (message.Length == 6) { Enum.TryParse<CallbackStatus>(message[4].ToString(), out CallbackStatus); } break; } } if (seqNumber == long.MaxValue) seqNumber = 0; Seq = ++seqNumber; Utility.logger.Debug("ZWaveMessage (RawData={0})", BitConverter.ToString(RawData)); if (Direction == MessageDirection.Inbound) Utility.logger.Debug("ZWaveMessage (Direction={0}, Header={1}, NodeId={2}, Type={3}, Function={4}, CommandClass={5})", Direction, Header, NodeId, Type, Function, CommandClass); else Utility.logger.Debug("ZWaveMessage (Direction={0}, Header={1}, NodeId={2}, Type={3}, Function={4}, CommandClass={5}, CallbackId={6}, CallbackStatus={7})", Direction, Header, NodeId, Type, Function, CommandClass, CallbackId, CallbackStatus); }
private void WriteFrameHeader(FrameHeader frameHeader) { _outgoingBuffer.EnsureAvailableSpace(FrameHeader.Size); frameHeader.WriteTo(_outgoingBuffer.AvailableSpan); _outgoingBuffer.Commit(FrameHeader.Size); }
public Popularimeter(FrameHeader header) : base(header) { }
/// <summary> /// Relays data that the local channel owner wants to send to the remote party. /// </summary> private async Task ProcessOutboundTransmissionsAsync() { try { // Don't transmit data on the channel until the remote party has accepted it. // This is not just a courtesy: it ensure we don't transmit data from the offering party before the offer frame itself. // Likewise: it may help prevent transmitting data from the accepting party before the acceptance frame itself. await this.Acceptance.ConfigureAwait(false); while (!this.Completion.IsCompleted) { ReadResult result; try { result = await this.mxStreamIOReader !.ReadAsync().ConfigureAwait(false); } catch (InvalidOperationException ex) { // Someone completed the reader. The channel was probably disposed. if (this.TraceSource !.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "Transmission terminated because the reader threw: {0}", ex); } break; } if (result.IsCanceled) { // We've been asked to cancel. Presumably the channel has been disposed. if (this.TraceSource !.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "Transmission terminated because the read was canceled."); } break; } // We'll send whatever we've got, up to the maximum size of the frame. // Anything in excess of that we'll pick up next time the loop runs. var bufferToRelay = result.Buffer.Slice(0, Math.Min(result.Buffer.Length, this.MultiplexingStream.framePayloadMaxLength)); if (this.TraceSource !.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "{0} of {1} bytes will be transmitted.", bufferToRelay.Length, result.Buffer.Length); } if (bufferToRelay.Length > 0) { FrameHeader header = new FrameHeader { Code = ControlCode.Content, ChannelId = this.Id, FramePayloadLength = (int)bufferToRelay.Length, }; await this.MultiplexingStream.SendFrameAsync(header, bufferToRelay, CancellationToken.None).ConfigureAwait(false); try { // Let the pipe know exactly how much we read, which might be less than we were given. this.mxStreamIOReader.AdvanceTo(bufferToRelay.End); } catch (InvalidOperationException ex) { // Someone completed the reader. The channel was probably disposed. if (this.TraceSource.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "Transmission terminated because the reader threw: {0}", ex); } break; } } if (result.IsCompleted) { if (this.TraceSource.Switch.ShouldTrace(TraceEventType.Verbose)) { this.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "Transmission terminated because the writer completed."); } break; } } this.mxStreamIOReader !.Complete(); } catch (Exception ex) { this.mxStreamIOReader !.Complete(ex); throw; } finally { this.MultiplexingStream.OnChannelWritingCompleted(this); } }
/// <summary> /// Send a 'pong' response /// </summary> /// <param name="header"></param> private void SendPong(FrameHeader header) { // Get the data we need to echo back byte[] buffer = new byte[MaxFrameSize]; if (!ReadData(header, buffer, 0)) return; SendFrame(PongFrame, buffer, 0, (int)header.Length); }