-
Notifications
You must be signed in to change notification settings - Fork 0
/
GBN.cpp
144 lines (115 loc) · 5.63 KB
/
GBN.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//
// GBN.cpp
// lab2
//
// Created by Nishad Krishnan on 2015-03-13.
// Copyright (c) 2015 Nish. All rights reserved.
//
#include "GBN.h"
GBN::GBN(int hLength, // Header length
int pLength, // Payload length
int tR, // Link Rate
double bER, // Bit Error Rate
int numPacketsForSim, // Number of Packets for Simulation
double channDelay, // Channel Delay for one way
double deltaTaoFactor, // Delta/Tau
int buffSize) // buffer size
:RetransmissionProtocol(hLength, pLength, tR, bER, numPacketsForSim, channDelay, deltaTaoFactor) {
bufferSize = buffSize;
}
void RunGBNSimulation(double bR, double deltaTaoFactor, double roundtripDelay) {
// one way delay from roundtrip delay from ms to s
double channelDelay = (roundtripDelay/2)/1000;
GBN simulator(
54*8, // Header Length in bits
1500*8, // Payload length in bits
5000000, // Link Rate in bits/sec
bR, // Bit error Rate
5000, // Number of packets for simulation
channelDelay, // One way channel delay
deltaTaoFactor, // Delta/Tau
4); // buffer size
simulator.Simulate(
false); // nak is set to false
}
//Sends Packets
void GBN::Sender(bool nak) {
//initializing local variables
int fullPacketLength = packetLength + frameHeaderLength; // total packet length in bits
double curTime = 0; // current time at sender
double timeoutVal = deltaTaoFactor * channelDelay; // calculate timeout value (delta/Tau * Tau)
int sequenceNum = 0; // the buffer index
int packetsDelivered = 0; // packets successfully delivered
bool addTimeout = true; // boolean for when to add timeouts
double times[bufferSize + 1]; // storing times for each packet in buffer
//Declaring Event Scheduler and Shifting Buffer Objects
EventScheduler scheduler;
ShiftingBuffer buffer(bufferSize);
//Initialize time values
for (int i = 0; i < (bufferSize + 1); i++) {
times[i] = 0;
}
//Fill buffer with initial values to send
buffer.Fill(bufferSize);
while (packetsDelivered < numPacketsToSend) {
//Queue Acks only if sequenceNum is valid.
if (sequenceNum < bufferSize) {
scheduler.QueueEvent(Send(curTime, buffer.GetValue(sequenceNum), fullPacketLength));
curTime += (double)fullPacketLength/(double)transmissionRate;
times[buffer.GetValue(sequenceNum)] = curTime;
}
//Purging Timeouts and Adding a new one
if (addTimeout) {
scheduler.PurgeTimeouts();
scheduler.QueueEvent(CreateEvent(TIMEOUT, times[buffer.GetValue(0)] + timeoutVal));
addTimeout = false;
}
//Sends all packets before the time of the next queued event
if (curTime < scheduler.GetFirstEvent()->time && sequenceNum < (bufferSize - 1)) {
sequenceNum++;
addTimeout = false;
continue;
}
else {
//Gets first event and sets curent time
Event* curEvent = scheduler.GetFirstEvent();
if (curEvent->time > curTime)
curTime = curEvent->time;
scheduler.DequeueEvent();
//Timeout
if (curEvent->type == TIMEOUT) {
sequenceNum = 0;
addTimeout = true;
}
else {
//Check if rN is valid
int rN = buffer.FindRN(curEvent->seqNum);
//No error and valid rN
if (curEvent->status == NOERROR && rN>= 0) {
int shiftAmount = buffer.ShiftAndFill(rN);
++sequenceNum -= shiftAmount;
//sequenceNum should never go below 0 since it is technically the buffer index
if (sequenceNum < 0)
sequenceNum = 0;
//Sets timeout to true in order to add timeout for oldest packet in buffer
addTimeout = true;
packetsDelivered += shiftAmount;
}
//Error or invalid rN
else if (curEvent->status == ERROR || rN < 0){
sequenceNum++; //Keep transmitting from buffer
}
}
}
}
//Final output of throughput
std::cout << (packetsDelivered*packetLength)/curTime;
}
//Receives Packets
int GBN::Receiver(double time, int sN, int status) {
//If noerror and sN is valid increment next expected frame, else return current one
if (status == NOERROR && nextExpectedFrame == sN) {
return ++nextExpectedFrame %= (bufferSize + 1);
}
return nextExpectedFrame;
}