00001 using System;
00002 using System.IO;
00003 using Common;
00004
00005 namespace ProtocolStack {
00006
00007 public class EmptyMessage : Message {
00009 public override byte[] RawData {
00010 get { return new byte[] {}; }
00011 }
00012
00013 public EmptyMessage() : base(MessageType.Noop) {}
00018 public EmptyMessage(ushort destinationDeviceID) : this() {
00019 this.Destination = destinationDeviceID;
00020 }
00021 }
00022
00023 public class RetransmissionMessage : Message {
00025 private Segment data;
00026
00028 public Segment RawSegment {
00029 get { return data; }
00030 }
00031 public override byte[] RawData {
00032 get { return data.ToByteArray(); }
00033 }
00034
00036 public RetransmissionMessage() : base(MessageType.Retransmission) {}
00037 public RetransmissionMessage(byte[] src) : this() {
00038 data = new Segment(src);
00039 }
00040 public RetransmissionMessage(Segment src) : this() {
00041 data = src;
00042 }
00043 }
00044
00045 public class MessageChunk : Message {
00046 private static readonly int MAX_DATA_SIZE = SegmentData.MAX_DATA_SIZE - 4 - 4 - 4 - 8 -2 -1;
00047
00048
00049
00050
00051 public int firstInMessage;
00052 public int lastInMessage;
00053 public int offset;
00054 public DateTime timestamp;
00055 public SegmentData segmentData;
00056
00057 public static MessageChunk[] GetChunksFromMessage(Message msg, ref DateTime lastTimestampUsed, ref int lastOffsetUsed) {
00058 SegmentData[] segmentDataArr = SegmentData.FromMessage(msg, MAX_DATA_SIZE);
00059 MessageChunk[] resultArr = new MessageChunk[segmentDataArr.Length];
00060 DateTime now = DateTime.Now;
00061 int currentOffset;
00062 if (now == lastTimestampUsed) {
00063 currentOffset = lastOffsetUsed + 1;
00064 } else {
00065 currentOffset = 0;
00066 }
00067 int initialOffset = currentOffset;
00068
00069 for(int i = 0; i < segmentDataArr.Length; i++) {
00070 resultArr[i] = new MessageChunk(segmentDataArr[i], now, currentOffset);
00071 resultArr[i].firstInMessage = initialOffset;
00072 resultArr[i].lastInMessage = initialOffset + segmentDataArr.Length - 1;
00073 currentOffset++;
00074 }
00075
00076 lastOffsetUsed = currentOffset;
00077 lastTimestampUsed = now;
00078 return resultArr;
00079 }
00080
00086 public static SegmentData[] GetMessageFromChunks(MessageChunk[] chunks) {
00087 SegmentData[] dataChunks = new SegmentData[chunks.Length];
00088 for(int i = 0; i < chunks.Length; i++) {
00089 dataChunks[i] = chunks[i].segmentData;
00090 }
00091 return dataChunks;
00092 }
00093
00094
00095 public MessageChunk(SegmentData data, DateTime timestamp, int offset) : base(MessageType.Chunk) {
00096 this.segmentData = data;
00097 this.timestamp = timestamp;
00098 this.offset = offset;
00099 }
00100
00101 public MessageChunk(byte[] src) : base(MessageType.Chunk) {
00102 Deserialise(src);
00103 }
00104
00105 public override byte[] RawData {
00106 get { return Serialise(); }
00107 }
00108
00109 public byte[] Serialise() {
00110 byte[] firstInMessageByte = BitConverter.GetBytes(this.firstInMessage);
00111 byte[] lastInMessageByte = BitConverter.GetBytes(this.lastInMessage);
00112 byte[] offsetBytes = BitConverter.GetBytes(this.offset);
00113 byte[] timestampBytes = BitConverter.GetBytes(this.timestamp.Ticks);
00114 byte[] result = new byte[firstInMessageByte.Length + lastInMessageByte.Length + offsetBytes.Length + timestampBytes.Length + segmentData.ToByteArray().Length];
00115 MemoryStream ms = new MemoryStream(result);
00116 ms.Write(firstInMessageByte, 0, firstInMessageByte.Length);
00117 ms.Write(lastInMessageByte, 0, lastInMessageByte.Length);
00118 ms.Write(offsetBytes, 0, offsetBytes.Length);
00119 ms.Write(timestampBytes, 0, timestampBytes.Length);
00120 ms.Write(segmentData.ToByteArray(), 0, segmentData.ToByteArray().Length);
00121 ms.Close();
00122 return result;
00123 }
00124
00125 public void Deserialise(byte[] src) {
00126 int currentPos = 0;
00127 firstInMessage = BitConverter.ToInt32(src, currentPos);
00128 currentPos+=4;
00129 lastInMessage = BitConverter.ToInt32(src, currentPos);
00130 currentPos+=4;
00131 offset = BitConverter.ToInt32(src, currentPos);
00132 currentPos += 4;
00133 timestamp = new DateTime(BitConverter.ToInt64(src, currentPos));
00134 currentPos += 8;
00135
00136
00137 segmentData = new SegmentData();
00138 segmentData.FromByteArray(ref src, ref currentPos);
00139 }
00140
00141 }
00142 }