public void CanSerializeAndDeserialize() { var infoPacket1 = new PsnInfoPacketChunk( new PsnInfoHeaderChunk(1500, 2, 1, 34, 1), new PsnInfoSystemNameChunk("Test System"), new PsnInfoTrackerListChunk( new PsnInfoTrackerChunk(0, new PsnInfoTrackerNameChunk("Test Tracker")) ) ); var infoData = infoPacket1.ToByteArray(); var infoPacket2 = PsnPacketChunk.FromByteArray(infoData); infoPacket1.Should() .Be(infoPacket2, "because the deserializing the serialized data should produce the same values"); var dataPacket1 = new PsnDataPacketChunk( new PsnDataHeaderChunk(1500, 2, 1, 34, 1), new PsnDataTrackerListChunk( new PsnDataTrackerChunk(0, new PsnDataTrackerPosChunk(0.45f, 7.56f, 2343.43f), new PsnDataTrackerSpeedChunk(0.34f, 5.76f, -876.87f), new PsnDataTrackerOriChunk(6.4f, -3.576f, 3873.3f), new PsnDataTrackerStatusChunk(54f), new PsnDataTrackerAccelChunk(4.34f, 23423.5f, 234.4f), new PsnDataTrackerTrgtPosChunk(23.3f, 4325f, 4234f), new PsnDataTrackerTimestampChunk(34524534454543543) ), new PsnDataTrackerChunk(1, new PsnDataTrackerPosChunk(-343.44f, 4.76f, 2.45f), new PsnDataTrackerSpeedChunk(34f, -23f, 5676.4f), new PsnDataTrackerOriChunk(24.7f, 3.53376f, 38.334f), new PsnDataTrackerStatusChunk(0.1f), new PsnDataTrackerAccelChunk(4234.34f, 543543.4f, 23.43f), new PsnDataTrackerTrgtPosChunk(2342.6f, 35.5f, -14545.4f), new PsnDataTrackerTimestampChunk(ulong.MaxValue) ) ) ); var dataData = dataPacket1.ToByteArray(); var dataPacket2 = PsnPacketChunk.FromByteArray(dataData); dataPacket1.Should() .Be(dataPacket2, "because the deserializing the serialized data should produce the same values"); }
/// <summary> /// Override to provide new behavior for transmission of PosiStageNet data packets /// </summary> /// <param name="trackers">Enumerable of trackers to send data packets for</param> protected virtual void OnSendData([NotNull] IEnumerable <PsnTracker> trackers) { var trackerChunks = trackers.Select(t => new PsnDataTrackerChunk(t.TrackerId, t.ToDataTrackerChunks())); var trackerListChunks = new List <PsnDataTrackerListChunk>(); var currentTrackerList = new List <PsnDataTrackerChunk>(); int trackerListLength = 0; int maxTrackerListLength = MaxPacketLength - (PsnChunk.ChunkHeaderLength // Root Chunk-Header + PsnDataHeaderChunk.StaticChunkAndHeaderLength // Packet Header Chunk + PsnChunk.ChunkHeaderLength); // Tracker List Chunk-Header foreach (var chunk in trackerChunks) { if (trackerListLength <= maxTrackerListLength) { currentTrackerList.Add(chunk); trackerListLength += chunk.ChunkAndHeaderLength; } else { trackerListChunks.Add(new PsnDataTrackerListChunk(currentTrackerList)); currentTrackerList = new List <PsnDataTrackerChunk>(); trackerListLength = 0; } } trackerListChunks.Add(new PsnDataTrackerListChunk(currentTrackerList)); ulong timestamp = (ulong)_timeStampReference.ElapsedMilliseconds; foreach (var trackerListChunk in trackerListChunks) { var packet = new PsnDataPacketChunk( new PsnDataHeaderChunk(timestamp, VersionHigh, VersionLow, _frameId, trackerListChunks.Count), trackerListChunk); var data = packet.ToByteArray(); Debug.Assert(data.Length <= MaxPacketLength); _udpService.SendAsync(data, _targetEndPoint).Wait(); } ++_frameId; }
/// <summary> /// Override to provide new behavior for receipt of a PosiStageNet data packet /// </summary> protected virtual void OnDataPacketReceived(PsnDataPacketChunk dataPacket) { if (dataPacket.SubChunks.Count(c => c.ChunkId == PsnDataPacketChunkId.PsnDataHeader) > 1) { InvalidPacketReceived?.Invoke(this, new InvalidPacketsReceivedEventArgs(dataPacket, false, "Packet contains multiple data packet header chunks")); return; } var headerChunk = (PsnDataHeaderChunk) dataPacket.SubChunks.FirstOrDefault(c => c.ChunkId == PsnDataPacketChunkId.PsnDataHeader); if (headerChunk == null) { InvalidPacketReceived?.Invoke(this, new InvalidPacketsReceivedEventArgs(dataPacket, false, "Packet missing data packet header chunk")); return; } if (_currentDataPacketChunks.Any()) { if (headerChunk.TimeStamp != _lastDataPacketHeader.TimeStamp || headerChunk.FramePacketCount != _lastDataPacketHeader.FramePacketCount) { InvalidPacketReceived?.Invoke(this, new InvalidPacketsReceivedEventArgs(_currentDataPacketChunks, false, "Incomplete packet chunk discarded, did not receive all packets for data frame")); _currentDataPacketChunks.Clear(); } } _lastDataPacketHeader = headerChunk; _currentDataPacketChunks.Add(dataPacket); if (_currentDataPacketChunks.Count == _lastDataPacketHeader.FramePacketCount) { OnCompleteDataFrameReceived(_lastDataPacketHeader, _currentDataPacketChunks); _currentDataPacketChunks.Clear(); } }