00001 using System;
00002 using System.Collections;
00003 using System.Threading;
00004 using Common;
00005
00006 namespace ProtocolStack
00007 {
00012 public class NACKManager
00013 {
00015 private NackQueue nackQueue;
00016 private TransmissionQueue txQueue;
00017 private RemoteHostComms thisRemoteHost;
00018
00020
00021
00022
00023 public NACKManager(RemoteHostComms thisRemoteHost) {
00024 this.thisRemoteHost = thisRemoteHost;
00025 nackQueue = new NackQueue();
00026 this.txQueue = thisRemoteHost.TxQueue;
00027 }
00028
00029 public void ResetConnections() {
00030 Console.WriteLine("NACK Manager Reset Starting ...");
00031 nackQueue.Clear();
00032 Console.WriteLine("... NACK Manager Reset Complete");
00033 }
00034
00039 public NackInfo GetNextNack() {
00040
00041 if (nackQueue.IsEmpty) { return null; }
00042 else return nackQueue.Dequeue();
00043 }
00044
00045 public void ProcessReceivedSegmentHeaders(ref SegmentHeaders newHeaders) {
00046
00047
00048
00049 uint lastNACK;
00050 uint firstNACK;
00051 ushort destination;
00052
00053 if (newHeaders.IsNACK) {
00054 firstNACK = newHeaders.NackInfo.SequenceNumber;
00055 if (newHeaders.NackInfo.IsRanged) { lastNACK = firstNACK + newHeaders.NackInfo.Range; }
00056 else { lastNACK = firstNACK; }
00057 destination = newHeaders.SourceDeviceID;
00058
00059
00060 for (uint i = firstNACK; i <= lastNACK; i++) {
00061
00062 Segment tempSegment = thisRemoteHost.RetransmissionBuffer.GetSegment(i);
00063
00064 RetransmissionMessage retransMessage = new RetransmissionMessage(tempSegment);
00065
00066 retransMessage.Destination = destination;
00067
00068 TransmissionQueueEntry[] entries = TransmissionQueueEntry.FromMessage(retransMessage);
00069 txQueue.Enqueue(entries, false);
00070 Console.WriteLine("NACK Manager: Issued Reransmision of #" + i);
00071 }
00072 }
00073 }
00074
00079 public void IssueNACK(uint segmentNumber) {
00080 SendNACK(new NackInfo(segmentNumber));
00081 }
00082
00088 public void IssueNACK(uint segmentNumber, long range) {
00089 for (long offset = 0; offset < range; offset++) {
00090 IssueNACK((uint)(segmentNumber + offset));
00091 }
00092
00093 }
00094
00095 private void SendNACK(NackInfo nackInfo) {
00096 lock (txQueue.SyncRoot) {
00097 if (txQueue.IsEmpty) {
00098
00099 Message noopMsg = new EmptyMessage();
00100 noopMsg.Destination = thisRemoteHost.RemoteDeviceID;
00101
00102 TransmissionQueueEntry[] buffer = TransmissionQueueEntry.FromMessage(noopMsg);
00103
00104
00105 txQueue.EnqueueUnprotected(buffer, false);
00106 }
00107 nackQueue.Enqueue(nackInfo);
00108 Console.WriteLine("NACK Manager: NACK Sent for #" + nackInfo.SequenceNumber + " Range: " + (nackInfo.IsRanged ? nackInfo.Range.ToString() : "N/A"));
00109 Monitor.PulseAll(txQueue.SyncRoot);
00110 }
00111 }
00112 }
00113
00114
00115 public class NackInfo {
00117 bool isRanged;
00118 uint sequenceNumber;
00119 uint range;
00120
00122 public NackInfo(uint sequenceNumber) {
00123 this.isRanged = false;
00124 this.sequenceNumber = sequenceNumber;
00125 }
00126
00127 public NackInfo(uint sequenceNumber, uint range) {
00128 this.isRanged = true;
00129 this.sequenceNumber = sequenceNumber;
00130 this.range = range;
00131 }
00132
00134 public bool IsRanged { get { return isRanged; }}
00135 public uint SequenceNumber { get { return sequenceNumber; } }
00136 public uint Range { get { return range; } }
00137
00138
00139 }
00140
00141
00142
00146 class NackQueue : Queue {
00147 public NackQueue() : base() {}
00148
00154 public void Enqueue(NackInfo nackInfo) {
00155 lock (this.SyncRoot) {
00156 base.Enqueue(nackInfo);
00157 }
00158 }
00159
00160 public new NackInfo Dequeue() {
00161 NackInfo result;
00162 lock (this.SyncRoot) {
00163 result = (NackInfo)base.Dequeue();
00164 }
00165 return result;
00166 }
00167
00168 public bool IsEmpty {
00169 get {
00170 bool result;
00171 lock (this.SyncRoot) {
00172 result = (this.Count == 0);
00173 }
00174 return result;
00175 }
00176 }
00177 }
00178
00179
00180 public class RetransmissionBuffer {
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00209 Hashtable buffer;
00210 private SequenceManager seqManager;
00211
00213 private uint earliestSegmentNumber {
00214 get {
00215
00216 lock (buffer.SyncRoot) {
00217 ICollection keys = buffer.Keys;
00218 uint[] keyArray = new uint[keys.Count];
00219 keys.CopyTo(keyArray, 0);
00220 Array.Sort(keyArray);
00221 return keyArray[0];
00222 }
00223 }
00224 }
00225
00227 public RetransmissionBuffer(SequenceManager seqManager) {
00228 this.seqManager = seqManager;
00229 buffer = new Hashtable();
00230 }
00231
00233
00234
00235
00236 public void ResetConnection() {
00237 lock (buffer.SyncRoot) {
00238 buffer.Clear();
00239 }
00240 }
00241
00242
00246 private void Add(Segment target) {
00247 lock (buffer.SyncRoot) {
00248 buffer.Add(target.Headers.SequenceNumber, target);
00249 }
00250
00251 }
00252
00256 private void Remove(uint segmentNumber) {
00257 lock (buffer.SyncRoot) {
00258 buffer.Remove(segmentNumber);
00259 }
00260 }
00261
00266 private Segment Read(uint segmentNumber) {
00267 lock (buffer.SyncRoot) {
00268 return (Segment)buffer[segmentNumber];
00269 }
00270 }
00271
00278 public Segment GetSegment(uint sequenceNumber) {
00279 lock (buffer.SyncRoot) {
00280 Segment result = null;
00281
00282 result = Read(sequenceNumber);
00283
00284
00285
00286 if (!seqManager.IsSegmentsMissing) {
00287
00288
00289 if (earliestSegmentNumber > sequenceNumber) {
00290 for (long i = sequenceNumber; i >= 0; i--) {
00291 this.Remove((uint)i); }
00292 for (long i = UInt32.MaxValue; i >= earliestSegmentNumber; i--) {
00293 this.Remove((uint)i); }
00294 } else {
00295 for (long i = sequenceNumber; i >= earliestSegmentNumber; i--) {
00296 this.Remove((uint)i); }
00297 }
00298 }
00299 return result;
00300 }
00301 }
00302
00307 public void PutSegment(Segment target) {
00308
00309 lock (buffer.SyncRoot) {
00310 this.Add(target);
00311 }
00312 }
00313
00314
00315 }
00316 }