00001 using System;
00002 using System.Collections.Specialized;
00003
00004 namespace ProtocolStack
00005 {
00011 public class SequenceManager
00012 {
00013 private uint nextInSendSequence;
00014 private uint expectedNextInReceiveSequence;
00015
00016 private bool nextInSequenceUnknown;
00017 private uint sendSequenceRoot = 0;
00018 private uint receiveSequenceRoot = 0;
00019
00020 private DateTime earliestMissing;
00021 private DateTime lastSeen;
00022
00023 private int resynchCount = 0;
00024
00025 private MissingList missingList;
00026 private NACKManager nackManager;
00027
00032 public SequenceManager(NACKManager nackManager) {
00033 Console.WriteLine("Creating Sequence Manager...");
00034 StartResynch();
00035 missingList = new MissingList();
00036 earliestMissing = DateTime.MinValue;
00037 lastSeen = DateTime.MinValue;
00038 nextInSequenceUnknown = true;
00039 this.nackManager = nackManager;
00040
00041 Console.WriteLine("... Sequence Manager Created");
00042 }
00043
00045 uint LastSeenNumber {
00046 get {return expectedNextInReceiveSequence - 1 ;}
00047 }
00048
00049 public bool IsSegmentsMissing {
00050 get { return missingList.AreSegmentsMissing; }
00051 }
00052
00054
00055
00056
00057 public void ResetConnection() {
00058 Console.WriteLine("Resetting Sequence Manager...");
00059 StartResynch();
00060 missingList.Clear();
00061 earliestMissing = DateTime.MinValue;
00062 lastSeen = DateTime.MinValue;
00063 nextInSequenceUnknown = true;
00064 Console.WriteLine("... Sequence Manager Reset");
00065 }
00066
00067 public uint GetNextSequenceNumber() {
00068 uint sequenceNumber;
00069
00070
00071 sequenceNumber = nextInSendSequence;
00072 nextInSendSequence = (uint)(((long)nextInSendSequence + 1L) % UInt32.MaxValue);
00073 return sequenceNumber;
00074 }
00075
00076 private void StartResynch() {
00077 Random r = new Random();
00078 nextInSendSequence = (uint)r.Next(1000,9999);
00079 sendSequenceRoot = nextInSendSequence;
00080 resynchCount = 3;
00081 }
00082
00087 public bool IsResynching {
00088 get { return (resynchCount != 0); }
00089 }
00090
00091 public uint GetSequenceOffset(uint number) {
00092
00093
00094 resynchCount--;
00095 return (uint)(number - sendSequenceRoot);
00096 }
00097
00098 public void ProcessReceivedSegmentHeaders(ref SegmentHeaders headers) {
00099 long numberOfMissingSegments = 0;
00100
00101
00102
00103
00104
00105
00106 if (nextInSequenceUnknown) {
00107 Console.WriteLine(" Next sequence # unknown, adopting #" + headers.SequenceNumber + " as next expected.");
00108 receiveSequenceRoot = headers.SequenceNumber;
00109 expectedNextInReceiveSequence = headers.SequenceNumber;
00110
00111 nextInSequenceUnknown = false;
00112 } else if (headers.IsResynch && !headers.IsRetransmission) {
00113 if (receiveSequenceRoot != headers.SequenceNumber - headers.SynchOrRate) {
00114 receiveSequenceRoot = (headers.SequenceNumber - headers.SynchOrRate);
00115 Console.WriteLine(" Resynch Detected. Adopting #" + receiveSequenceRoot + " as root of new sequence");
00116 expectedNextInReceiveSequence = headers.SequenceNumber ;
00117 Console.WriteLine(" Checking for missing segments at start of sequence");
00118 for (uint i = receiveSequenceRoot; i < headers.SequenceNumber; i++) {
00119 Console.WriteLine("SeqManager: Mismatch between new sequence root and new segment. Issuing NACK");
00120 nackManager.IssueNACK(i);
00121 missingList.Add(i, lastSeen);
00122 earliestMissing = missingList.GetEarliestMissingTime();
00123 }
00124 Console.WriteLine(" New sequence init complete");
00125 }
00126 }
00127
00128
00129
00130
00131
00132 if (missingList.IsMissing(headers.SequenceNumber)) {
00133 missingList.Remove(headers.SequenceNumber);
00134 earliestMissing = missingList.GetEarliestMissingTime();
00135 if (earliestMissing == DateTime.MaxValue) {
00136 earliestMissing = lastSeen;
00137 }
00138 }
00139
00140 else {
00141 if (headers.SequenceNumber != expectedNextInReceiveSequence) {
00142 numberOfMissingSegments = (long)headers.SequenceNumber - (long)expectedNextInReceiveSequence;
00143 if (numberOfMissingSegments == 1) {
00144 nackManager.IssueNACK(expectedNextInReceiveSequence);
00145 missingList.Add(expectedNextInReceiveSequence, lastSeen);
00146 }
00147 else {
00148 nackManager.IssueNACK(expectedNextInReceiveSequence, numberOfMissingSegments);
00149 for (int i = 0; i < numberOfMissingSegments; i++) {
00150 missingList.Add((uint)(expectedNextInReceiveSequence + i), lastSeen);
00151 }
00152 }
00153
00154 earliestMissing = missingList.GetEarliestMissingTime();
00155 }
00156 expectedNextInReceiveSequence = (uint)(((ulong)headers.SequenceNumber + 1L) % UInt32.MaxValue);
00157
00158 lastSeen = headers.TimeSent;
00159 }
00160
00161 }
00162
00163 public bool IsProcessable(SegmentHeaders headers) {
00164 bool result = true;
00165 if (headers.TimeSent < earliestMissing) {
00166 result = false;
00167 }
00168
00169 else if (headers.TimeSent == lastSeen) {
00170 if (headers.SequenceNumber == LastSeenNumber) { result = false; }
00171 else if ((headers.SequenceNumber < LastSeenNumber) && (!missingList.IsMissing(headers.SequenceNumber))) { result = false; }
00172 }
00173
00174 else if (headers.TimeSent < lastSeen) {
00175 if (!missingList.IsMissing(headers.SequenceNumber)) { result = false; }
00176 }
00177
00178
00179
00180
00181 if (headers.IsRetransmission)
00182 result = true;
00183
00184 return result;
00185 }
00186
00187 }
00188
00192 class MissingList : HybridDictionary {
00199 public bool IsMissing(uint target) {
00200 return Contains(target);
00201 }
00202
00207 public void Remove(uint sequenceNumber) {
00208 base.Remove(sequenceNumber);
00209 }
00210
00216 public void Add(uint sequenceNumber, DateTime lastSeen) {
00217 base.Add(sequenceNumber, lastSeen);
00218 }
00219
00225 public DateTime GetEarliestMissingTime() {
00226 DateTime result = DateTime.MaxValue;
00227 DateTime[] listValues = new DateTime[Values.Count];
00228 this.Values.CopyTo(listValues, 0);
00229 foreach (DateTime dt in listValues) {
00230 if (dt < result) { result = dt; }
00231 }
00232 return result;
00233 }
00234
00239 public bool AreSegmentsMissing {
00240 get { return (Count != 0); }
00241 }
00242
00243 }
00244 }