public Tpm2BlockData(IPEndPoint endPoint, InternalBlockData blockData) { EndPoint = endPoint; PacketNumber = blockData.PacketNumber; TotalPackets = blockData.TotalPackets; Type = blockData.Type; Data = blockData.DataStream.ToArray(); }
public Tpm2NetSink([System.Runtime.CompilerServices.CallerMemberName] string name = "", int listenPort = 65506) { this.log = Log.Logger; dataReceived = new Subject <Tpm2BlockData>(); this.cancelSource = new System.Threading.CancellationTokenSource(); Task.Run(async() => { using (var udpClient = new UdpClient(listenPort)) { var clientBuffer = new Dictionary <IPEndPoint, InternalBlockData>(); while (!this.cancelSource.IsCancellationRequested) { //IPEndPoint object will allow us to read datagrams sent from any source. var receivedResults = await udpClient.ReceiveAsync(); InternalBlockData existingData; clientBuffer.TryGetValue(receivedResults.RemoteEndPoint, out existingData); if (existingData == null) { // New block if (receivedResults.Buffer.Length < 5) { // Invalid continue; } if (receivedResults.Buffer[0] != TPM2net_BlockStart) { // No start identifier continue; } if (receivedResults.Buffer.Length < 7) { // Tpm2Net minimum size is 7 bytes (0 bytes of data, not sure if perhaps it should be minimum 8) continue; } BlockTypes blockType; switch (receivedResults.Buffer[1]) { case TPM2_BlockType_Data: blockType = BlockTypes.Data; break; case TPM2_BlockType_Command: blockType = BlockTypes.Command; break; case TPM2_BlockType_Response: blockType = BlockTypes.Response; break; default: // Unknown continue; } int blockSize = ((int)receivedResults.Buffer[2] << 8) + receivedResults.Buffer[3]; existingData = new InternalBlockData { Size = blockSize, Type = blockType, PacketNumber = receivedResults.Buffer[4], TotalPackets = receivedResults.Buffer[5], DataStream = new MemoryStream(blockSize) }; int availableBytes = Math.Min(blockSize, receivedResults.Buffer.Length - 7); existingData.DataStream.Write(receivedResults.Buffer, 6, availableBytes); } else { // Continue int availableBytes = Math.Min(existingData.Size, receivedResults.Buffer.Length - 1); existingData.DataStream.Write(receivedResults.Buffer, 0, availableBytes); } if (existingData.DataStream.Length == existingData.Size) { // Completed, check end of block if (receivedResults.Buffer[receivedResults.Buffer.Length - 1] != TPM2_BlockEnd) { // Missing, throw away existingData.Dispose(); if (clientBuffer.ContainsKey(receivedResults.RemoteEndPoint)) { clientBuffer.Remove(receivedResults.RemoteEndPoint); } continue; } // All good #if DEBUG_LOG log.Debug("Received block of {0} bytes", existingData.DataStream.Length); #endif this.dataReceived.OnNext(new Tpm2BlockData(receivedResults.RemoteEndPoint, existingData)); existingData.Dispose(); } else { // Not received everything yet if (!clientBuffer.ContainsKey(receivedResults.RemoteEndPoint)) { clientBuffer.Add(receivedResults.RemoteEndPoint, existingData); } } } foreach (InternalBlockData blockData in clientBuffer.Values) { blockData.Dispose(); } clientBuffer.Clear(); } }); Executor.Current.Register(this); }
public Tpm2NetSink([System.Runtime.CompilerServices.CallerMemberName] string name = "", int listenPort = 65506) { dataReceived = new Subject<Tpm2BlockData>(); this.cancelSource = new System.Threading.CancellationTokenSource(); Task.Run(async () => { using (var udpClient = new UdpClient(listenPort)) { var clientBuffer = new Dictionary<IPEndPoint, InternalBlockData>(); while (!this.cancelSource.IsCancellationRequested) { //IPEndPoint object will allow us to read datagrams sent from any source. var receivedResults = await udpClient.ReceiveAsync(); InternalBlockData existingData; clientBuffer.TryGetValue(receivedResults.RemoteEndPoint, out existingData); if (existingData == null) { // New block if (receivedResults.Buffer.Length < 5) // Invalid continue; if (receivedResults.Buffer[0] != TPM2net_BlockStart) // No start identifier continue; if (receivedResults.Buffer.Length < 7) // Tpm2Net minimum size is 7 bytes (0 bytes of data, not sure if perhaps it should be minimum 8) continue; BlockTypes blockType; switch (receivedResults.Buffer[1]) { case TPM2_BlockType_Data: blockType = BlockTypes.Data; break; case TPM2_BlockType_Command: blockType = BlockTypes.Command; break; case TPM2_BlockType_Response: blockType = BlockTypes.Response; break; default: // Unknown continue; } int blockSize = ((int)receivedResults.Buffer[2] << 8) + receivedResults.Buffer[3]; existingData = new InternalBlockData { Size = blockSize, Type = blockType, PacketNumber = receivedResults.Buffer[4], TotalPackets = receivedResults.Buffer[5], DataStream = new MemoryStream(blockSize) }; int availableBytes = Math.Min(blockSize, receivedResults.Buffer.Length - 7); existingData.DataStream.Write(receivedResults.Buffer, 6, availableBytes); } else { // Continue int availableBytes = Math.Min(existingData.Size, receivedResults.Buffer.Length - 1); existingData.DataStream.Write(receivedResults.Buffer, 0, availableBytes); } if (existingData.DataStream.Length == existingData.Size) { // Completed, check end of block if (receivedResults.Buffer[receivedResults.Buffer.Length - 1] != TPM2_BlockEnd) { // Missing, throw away existingData.Dispose(); if (clientBuffer.ContainsKey(receivedResults.RemoteEndPoint)) clientBuffer.Remove(receivedResults.RemoteEndPoint); continue; } // All good #if DEBUG_LOG log.Debug("Received block of {0} bytes", existingData.DataStream.Length); #endif this.dataReceived.OnNext(new Tpm2BlockData(receivedResults.RemoteEndPoint, existingData)); existingData.Dispose(); } else { // Not received everything yet if (!clientBuffer.ContainsKey(receivedResults.RemoteEndPoint)) { clientBuffer.Add(receivedResults.RemoteEndPoint, existingData); } } } foreach (InternalBlockData blockData in clientBuffer.Values) blockData.Dispose(); clientBuffer.Clear(); } }); Executor.Current.Register(this); }