diff --git a/a.out.dSYM/Contents/Info.plist b/a.out.dSYM/Contents/Info.plist
new file mode 100644
index 0000000..3679a65
--- /dev/null
+++ b/a.out.dSYM/Contents/Info.plist
@@ -0,0 +1,20 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleIdentifier
+ com.apple.xcode.dsym.a.out
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundlePackageType
+ dSYM
+ CFBundleSignature
+ ????
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/f.txt b/f.txt
new file mode 100644
index 0000000..0928128
--- /dev/null
+++ b/f.txt
@@ -0,0 +1,366 @@
+lambda: 0.01
+T: 20
+Throughput: 308.701 Bps
+Average Network Delay: 8.26926e-07 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 40
+Throughput: 31.8001 Bps
+Average Network Delay: 3.12177e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 80
+Throughput: 241.501 Bps
+Average Network Delay: 9.86634e-07 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 160
+Throughput: 122.1 Bps
+Average Network Delay: 1.92688e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 320
+Throughput: 97.6004 Bps
+Average Network Delay: 4.78762e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 400
+Throughput: 97.1004 Bps
+Average Network Delay: 4.78138e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.05
+T: 20
+Throughput: 1279.03 Bps
+Average Network Delay: 8.88095e-07 s/B
+Average Network Delay: 0.000946561 s/packet
+Average Network Delay (per instructions): 8.88073e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 40
+Throughput: 849.72 Bps
+Average Network Delay: 1.14496e-06 s/B
+Average Network Delay: 0.000810727 s/packet
+Average Network Delay (per instructions): 1.14493e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 80
+Throughput: 812.92 Bps
+Average Network Delay: 1.42929e-06 s/B
+Average Network Delay: 0.000968227 s/packet
+Average Network Delay (per instructions): 1.42926e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 160
+Throughput: 950.123 Bps
+Average Network Delay: 1.69863e-06 s/B
+Average Network Delay: 0.00134489 s/packet
+Average Network Delay (per instructions): 1.69859e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 320
+Throughput: 1091.73 Bps
+Average Network Delay: 3.01445e-06 s/B
+Average Network Delay: 0.00274239 s/packet
+Average Network Delay (per instructions): 3.01438e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 400
+Throughput: 419.51 Bps
+Average Network Delay: 6.62425e-06 s/B
+Average Network Delay: 0.00231573 s/packet
+Average Network Delay (per instructions): 6.62409e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.1
+T: 20
+Throughput: 2231.71 Bps
+Average Network Delay: 9.29801e-07 s/B
+Average Network Delay: 0.00086456 s/packet
+Average Network Delay (per instructions): 9.29756e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 40
+Throughput: 1513.97 Bps
+Average Network Delay: 1.19423e-06 s/B
+Average Network Delay: 0.00075331 s/packet
+Average Network Delay (per instructions): 1.19417e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 80
+Throughput: 1974.59 Bps
+Average Network Delay: 1.40083e-06 s/B
+Average Network Delay: 0.00115248 s/packet
+Average Network Delay (per instructions): 1.40076e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 160
+Throughput: 1723.88 Bps
+Average Network Delay: 1.99556e-06 s/B
+Average Network Delay: 0.00143331 s/packet
+Average Network Delay (per instructions): 1.99546e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 320
+Throughput: 2161.6 Bps
+Average Network Delay: 2.68931e-06 s/B
+Average Network Delay: 0.00242206 s/packet
+Average Network Delay (per instructions): 2.68918e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 400
+Throughput: 2001.2 Bps
+Average Network Delay: 3.08128e-06 s/B
+Average Network Delay: 0.00256914 s/packet
+Average Network Delay (per instructions): 3.08113e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.3
+T: 20
+Throughput: 5703.78 Bps
+Average Network Delay: 9.20996e-07 s/B
+Average Network Delay: 0.000772418 s/packet
+Average Network Delay (per instructions): 9.20871e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 40
+Throughput: 6070.34 Bps
+Average Network Delay: 1.06254e-06 s/B
+Average Network Delay: 0.000921299 s/packet
+Average Network Delay (per instructions): 1.06239e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.3
+T: 80
+Throughput: 4687.34 Bps
+Average Network Delay: 1.40599e-06 s/B
+Average Network Delay: 0.000969035 s/packet
+Average Network Delay (per instructions): 1.4058e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 160
+Throughput: 3632.19 Bps
+Average Network Delay: 2.43176e-06 s/B
+Average Network Delay: 0.00129874 s/packet
+Average Network Delay (per instructions): 2.43143e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 320
+Throughput: 6025.24 Bps
+Average Network Delay: 2.72344e-06 s/B
+Average Network Delay: 0.00234387 s/packet
+Average Network Delay (per instructions): 2.72306e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.3
+T: 400
+Throughput: 5730.1 Bps
+Average Network Delay: 3.0147e-06 s/B
+Average Network Delay: 0.00246744 s/packet
+Average Network Delay (per instructions): 3.01428e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.6
+T: 20
+Throughput: 11168.7 Bps
+Average Network Delay: 9.5311e-07 s/B
+Average Network Delay: 0.000831432 s/packet
+Average Network Delay (per instructions): 9.52867e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 128
+------------------------------------------------------
+lambda: 0.6
+T: 40
+Throughput: 9911.4 Bps
+Average Network Delay: 1.10231e-06 s/B
+Average Network Delay: 0.000866879 s/packet
+Average Network Delay (per instructions): 1.10203e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 80
+Throughput: 10761 Bps
+Average Network Delay: 1.2735e-06 s/B
+Average Network Delay: 0.00108736 s/packet
+Average Network Delay (per instructions): 1.27318e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 160
+Throughput: 10981.2 Bps
+Average Network Delay: 1.78939e-06 s/B
+Average Network Delay: 0.0015591 s/packet
+Average Network Delay (per instructions): 1.78894e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 320
+Throughput: 8163.86 Bps
+Average Network Delay: 3.50556e-06 s/B
+Average Network Delay: 0.00227077 s/packet
+Average Network Delay (per instructions): 3.50468e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 400
+Throughput: 10973.4 Bps
+Average Network Delay: 3.42795e-06 s/B
+Average Network Delay: 0.00280644 s/packet
+Average Network Delay (per instructions): 3.42704e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 134
+------------------------------------------------------
+lambda: 0.8
+T: 20
+Throughput: 14293.4 Bps
+Average Network Delay: 9.2127e-07 s/B
+Average Network Delay: 0.000792997 s/packet
+Average Network Delay (per instructions): 9.20965e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 40
+Throughput: 15190.9 Bps
+Average Network Delay: 1.03502e-06 s/B
+Average Network Delay: 0.000946853 s/packet
+Average Network Delay (per instructions): 1.03468e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 80
+Throughput: 11400.2 Bps
+Average Network Delay: 1.45895e-06 s/B
+Average Network Delay: 0.00100161 s/packet
+Average Network Delay (per instructions): 1.45846e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 160
+Throughput: 14805.4 Bps
+Average Network Delay: 1.81492e-06 s/B
+Average Network Delay: 0.00161818 s/packet
+Average Network Delay (per instructions): 1.81432e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 320
+Throughput: 14111.3 Bps
+Average Network Delay: 2.78043e-06 s/B
+Average Network Delay: 0.00233467 s/packet
+Average Network Delay (per instructions): 2.7795e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 168
+------------------------------------------------------
+lambda: 0.8
+T: 400
+Throughput: 13067.2 Bps
+Average Network Delay: 3.4313e-06 s/B
+Average Network Delay: 0.00270017 s/packet
+Average Network Delay (per instructions): 3.43016e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.9
+T: 20
+Throughput: 14621.9 Bps
+Average Network Delay: 9.75482e-07 s/B
+Average Network Delay: 0.000774898 s/packet
+Average Network Delay (per instructions): 9.75125e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 184
+------------------------------------------------------
+lambda: 0.9
+T: 40
+Throughput: 15429.4 Bps
+Average Network Delay: 1.12303e-06 s/B
+Average Network Delay: 0.000951725 s/packet
+Average Network Delay (per instructions): 1.12262e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 80
+Throughput: 15956.5 Bps
+Average Network Delay: 1.29028e-06 s/B
+Average Network Delay: 0.00113082 s/packet
+Average Network Delay (per instructions): 1.28981e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 160
+Throughput: 13024.3 Bps
+Average Network Delay: 1.92281e-06 s/B
+Average Network Delay: 0.00139079 s/packet
+Average Network Delay (per instructions): 1.92211e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 180
+------------------------------------------------------
+lambda: 0.9
+T: 320
+Throughput: 14204.8 Bps
+Average Network Delay: 3.03224e-06 s/B
+Average Network Delay: 0.00236575 s/packet
+Average Network Delay (per instructions): 3.03114e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 400
+Throughput: 15867.7 Bps
+Average Network Delay: 3.1339e-06 s/B
+Average Network Delay: 0.0027313 s/packet
+Average Network Delay (per instructions): 3.13276e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
diff --git a/fwlan.cpp b/fwlan.cpp
new file mode 100644
index 0000000..57df419
--- /dev/null
+++ b/fwlan.cpp
@@ -0,0 +1,837 @@
+#include
+#include
+#include
+#include
+#include // max
+#include
+#include
+#include // for hooman random stuff
+
+
+// these should be constant for our project
+ const double maxRTM = 3; // maximum number of retransmissions
+ const int maxPktSize = 1544; // maximum size of a packet in bytes
+ const int ackPktSize = 64; // acknowledgement packet size in bytes
+ const double channelCapacity = 11000000.0; // 11 Mbps (bits)
+ const double SIFS = 0.00005; // 0.05 msec, delay before ack
+ const double DIFS = 0.0001; // 0.1 msec, delay before send
+ const double SYNC = 0.00001; // 0.01 msec
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*std::log(1-u));
+}
+
+double dataLengthFrame(double rate)
+{
+ // http://en.cppreference.com/w/cpp/numeric/random/exponential_distribution
+ std::random_device rd;
+ std::mt19937 gen(rd());
+
+ std::exponential_distribution<> d(1); // generate nedt between 0 and 1
+
+ return int(maxPktSize * d(gen));
+}
+
+double transmissionTime(int bytes)
+{
+ return (bytes * 8) / (channelCapacity);
+}
+
+// generate a random backoff value less than or equal to T that is not currently in the backoff list
+int generateRandomBackOff(int T, const int backoff[], int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(1, T); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+
+ // make sure the backoff value is not already given to another node
+ // this is for collision avoidance as the TA told us to do, even though
+ // it doesn't really happen in real life.
+ for (int i = 0; i < N; i++)
+ {
+ if (rd == backoff[i])
+ {
+ return generateRandomBackOff(T, backoff, N);
+ }
+ }
+ return rd;
+}
+
+int randomDestination(int source, int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, N - 1); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ rd = randomDestination(source, N);
+ }
+ return rd;
+}
+
+enum eventtype {
+ arrival, departure, sync, timeout
+};
+
+
+class Event {
+protected:
+ double eventTime;
+ eventtype type;
+
+
+public:
+ Event(eventtype type, double etime): eventTime(etime), type(type) {}
+ virtual ~Event(){}
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ eventtype getType()
+ {
+ return type;
+ }
+
+};
+
+class Arrival: public Event {
+ static double lambda;
+
+ int host;
+
+public:
+ Arrival(double stime, int h): Event(arrival, stime + nedt(lambda)), host(h) {}
+
+ static void setLambda(double l)
+ {
+ lambda = l;
+ }
+
+ int getHost()
+ {
+ return host;
+ }
+
+};
+
+double Arrival::lambda = 0;
+
+class Departure: public Event {
+
+ // shape of packet size distribution
+ static double mu;
+
+ bool ack; // denotes if it is an acknowedgement packet
+ int source; // source host
+ int destination; // destination host
+ int packetID; // id of packet, see host class
+ int size; // paket size in bytes, used to determine throughput
+
+public:
+ Departure(double stime, int s, int d, int id, bool a): Event(departure, stime), ack(a), source(s), destination(d), packetID(id)
+ {
+ // if ack packet, set the time to be that size
+ // time already current time, so just need to add the new time.
+ if(ack)
+ {
+ // this shouldn't be how it works in real life
+ // we're supposed to scan the channel during sifs,
+ // then if clear set channel to busy and transmit.
+ // For this project TA say just add SIFS, which is easier so OK then
+ size = ackPktSize;
+ eventTime += (SIFS + transmissionTime(size));
+ }
+ else
+ {
+ // same comment as above, except DFIS
+ size = dataLengthFrame(mu);
+ eventTime += (DIFS + transmissionTime(size));
+
+ }
+
+ }
+
+ static void setMu(double m)
+ {
+ mu = m;
+ }
+
+ bool isAck()
+ {
+ return ack;
+ }
+
+ int getSource()
+ {
+ return source;
+ }
+ int getDestination()
+ {
+ return destination;
+ }
+ int getPacketID()
+ {
+ return packetID;
+ }
+ int getSize()
+ {
+ return size;
+ }
+
+
+};
+
+double Departure::mu = 0;
+
+class Sync: public Event {
+
+ static double SYNC;
+
+public:
+ Sync(double stime): Event(sync, stime + SYNC) {}
+
+ static void setSYNC(double s)
+ {
+ SYNC = s;
+ }
+
+};
+
+double Sync::SYNC = 0;
+
+class Timeout: public Event{
+
+ static double to_time;
+
+ int host;
+ int timeoutID;
+public:
+ Timeout(double stime, int h, int id): Event(timeout, stime + to_time), host(h), timeoutID(id) {}
+
+ static void setTO(double t)
+ {
+ to_time = t;
+ }
+
+
+ int getHost()
+ {
+ return host;
+ }
+
+ int getTimeoutID()
+ {
+ return timeoutID;
+ }
+
+};
+
+double Timeout::to_time = 0;
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list(); // this line may not be necessary, but oh well
+ }
+
+ void insert(Event *event) {
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if ((*itr)->getEventTime() > event->getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ } // insert sorted by events time
+
+ Event* removeFirst() {
+
+ Event *firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+// not sure i need all this stuff yet
+class Packet {
+ int destination;
+ bool isAck; // true acknowledgement, false datapacket
+ int ackID; // used to make sure ack makes sense and stuff
+ double queueTime; // time when packet first queued, used for statistics (Network delay)
+
+
+ friend class Host;
+
+public:
+ Packet(double t, int dest, bool ack, int id = 0): destination(dest), isAck(ack), ackID(id), queueTime(t){}
+
+
+};
+
+class Host {
+ static int NumHosts; // need to know this in order to create random destination
+ static int T; // maximum backoff given no retransmissions
+ // static array so we can implement collision avoidance
+ static int* backoff; // doing it in syc tics versus real time because easier for conflict avoidance
+ // backoff < 0 means nothing in queue (nothing to transmit)
+ // backoff > 0 means waiting to transmit
+ // backoff == 0 means either transmitting or waiting for ack
+
+ int packetID; // the number of the packet sent.
+ // Not worring about overflow, and even it it does, it should still work correctly.
+ // Used to cordinate acks and timeouts.
+ // If a timeout occurs, there's a chance that there will be acks in the network
+ // that don't refer to the most recent transmission.
+
+ int droppedPackets; // not necessary for our project, but i think it might be interesting to keep track of
+ int hostID; // position in hosts array, maybe don't need this, but might if put create packets and stuff
+ int tmNum; // transmission number, max tmNum = 1 + maxRTM. Max backoff = tmNum * T
+
+ double retransmitTime; // used to calculate delay when there has been a retransmission
+ double delay; // total delay, used for statistics.
+ std::queue packetQueue; // i think its initialized implicitly
+
+public:
+ // initially set backoff to (-1) to show that nothing in queue
+ Host(int id): packetID(0), droppedPackets(0), hostID(id), tmNum(0), retransmitTime(0), delay(0){
+ backoff[id] = -1;
+ }
+
+ // initialize static variables
+ static void initHosts(int N, int t)
+ {
+ NumHosts = N;
+ backoff = new int[N];
+ T = t;
+ }
+
+ double getDelay()
+ {
+ return delay;
+ }
+
+ int getDropedPackets()
+ {
+ return droppedPackets;
+ }
+
+ void enqueueDataPacket(double stime)
+ {
+ packetQueue.push(Packet(stime, randomDestination(hostID, NumHosts), false));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet.
+ // in real life I don't think the first packet waits for a backoff,
+ // but the TAs told us to do it this way.
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+ void enqueueAckPacket(double stime, int dest, int ackID)
+ {
+
+ // In real life I don't think the ack goes in the back of the queue,
+ // But the TAs told us to do it this way.
+
+ packetQueue.push(Packet(stime, dest, true, ackID));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+
+ }
+
+ // decrements backoff value if it is larger than zero
+ // returns true if this act makes the value 0, and thus the Host is ready to transmit
+ bool decrementBackoff()
+ {
+ if (backoff[hostID] > 0)
+ {
+ --(backoff[hostID]);
+ if(backoff[hostID] == 0)
+ return true;
+ }
+ return false;
+ }
+
+
+ void receiveAck(int AckID)
+ {
+ // if correct ack, can pop packet from start of queue
+ if (AckID == packetID)
+ {
+ //std::cerr << "receive correct ack, Host: " << hostID << ", AckID: " << AckID << std::endl;
+ packetQueue.pop(); // pop packet from queue
+ packetID++; // new packet to send, so increment packetID
+ tmNum = 0; // need to reset TmNum because new packet to transmit.
+ // if no more packets in queue, indicate it by setting backoff id to -1
+ if (packetQueue.empty())
+ {
+ backoff[hostID] = -1;
+ }
+ // eles if still packet to send, set new backoff value
+ else
+ {
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+
+
+ }
+ // if AckID does not match PacketID do nothing
+ // should never get out of order ack because can only sent 1 packet at a time
+ }
+
+ void receiveTimeout(double stime, int TO_ID)
+ {
+ // if timeout refers to current packet, need to resend with larger backoff
+ if (TO_ID == packetID)
+ {
+ // if haven't reached maximum transmissions yet, need to retransmit it by resetting backoff value
+ // tmNum refers to current transmission. On transmission 3, there have been 2 retransmissions
+ // if MaxRTM = 3, then should be able to send another one.
+ // if MaxRTM = 3 and tmNum = 4, then there have already been 3 retransmissions and need to abort
+ if (tmNum <= maxRTM)
+ {
+ // need to reset packet queue time because should not double count delay when waiting for ack
+ // actually, i don't want to make it a queue of pointers so i'll do this hack instead
+ retransmitTime = stime;
+
+ // need to increase mack backoff by a multiple of (tmNum + 1),
+ // since tmNum in incremented when departure event created, but need to use that as a multiplyer here
+ backoff[hostID] = generateRandomBackOff(T * (tmNum + 1), backoff, NumHosts);
+ }
+ // else need to drop packet. Do this by pretending to ack it
+ else
+ {
+ droppedPackets++;
+ receiveAck(packetID);
+
+ }
+
+ }
+
+ }
+
+
+ // performs packet processing and prepares packet for departure
+ // returns a departure event
+ // not going to do error checking, so assumes that there is at least 1 packet in the queue and that hopeufully backoff == 0
+ // actually, maybe will do error checking
+ Departure* createDeparture(double stime)
+ {
+ // i lied, error checking
+ if (backoff[hostID] != 0)
+ std::cerr << "Host creating Departure event when backoff != 0" << std::endl;
+ // the other one should cause runtime issues if bug, so won't check for it
+ // no that's stupid
+ if (packetQueue.empty())
+ {
+ std::cerr << "Host creating Departure event when queue empty" << std::endl;
+
+ return NULL;
+ }
+
+
+
+ // get packet info
+ Packet p = packetQueue.front();
+
+ Departure* depart; // holds return value
+
+
+ //std::cerr << "creating departure with destination: " << p.destination << std::endl;
+
+ // if an ack packet, create ack event
+ // since we don't need to wait for ack, can immediatley pretend we got one
+ if (p.isAck)
+ {
+ receiveAck(packetID);
+ depart = new Departure(stime, hostID, p.destination, p.ackID, true);
+ }
+ // else need to create packet and increment tmNum
+ else
+ {
+ depart = new Departure(stime, hostID, p.destination, packetID, false);
+ tmNum ++;
+
+
+ }
+
+ // calculate delay
+ // if this is a retransmission (tmNum > 1), then need to use retransmitTime as a base
+ if (tmNum > 1)
+ {
+ delay += (depart->getEventTime() - retransmitTime);
+ }
+ // else use packet time as a base
+ else
+ {
+ delay += (depart->getEventTime() - p.queueTime);
+ }
+
+ return depart;
+
+ }
+
+ Timeout* createTimeout(double stime)
+ {
+ return new Timeout(stime, hostID, packetID);
+ }
+
+};
+
+int* Host::backoff = NULL;
+int Host::NumHosts = 0;
+int Host::T = 0;
+
+
+
+int main(int argc, char const *argv[])
+{
+
+// read from command line, but given default values
+ double lambda = 0.01; // dexcribes shape of arrival distribution
+ double mu = 1; // describes shape of distribution of PktSize (r)
+ int N = 20; // number of hosts in network.
+ int T = 400; // maximum backoff value in number sync cycles. Should be larger than N I suppose.
+ double TO = 0.005; // for project, will take values of 5, 10, or 15 msec.
+ int eventsSimulated = 1000000; // the bound of for loop
+
+// these are variables used throught the program
+ double time = 0; // time simulated since start of simulation in seconds
+ double transmitted = 0; // number of bytes successfully transmitted (will include ack bytes)
+ double delay = 0; // queue + transmission delay in seconds
+ int packets = 0;
+ bool channelBusy = false; // true if channel is busy, false otherwise
+
+// containers
+ Host* *hosts; // an array of host pointers
+ GEL* eventList; // holds list of events
+
+ // check if help option set (or if only 1 argument, since that would be invalid).
+ // If so, print help information and end program
+ if ((argc > 1 && std::string("-help") == argv[1]) || argc == 2)
+ {
+ std::cout << "\nThis program simulates an IEEE 802.11-Based Wireless LAN. \n"
+ "To set parameters of network, use the following commands.\n"
+ "Default values are given in parenthesis.\n\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n"
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n"<< std::endl;
+
+ return 0;
+ }
+
+ // read in command line inputs, assume all inputs come in a -var val pair
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ // i probably should have made this a function, but i already did the copy paste so really no use now
+ if (std::string("-N") == argv[i])
+ try{
+ N = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -N, using default value " << N << std::endl;
+ }
+ else if (std::string("-l") == argv[i])
+ try{
+ lambda = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -l, using default value " << lambda << std::endl;
+ }
+ else if (std::string("-m") == argv[i])
+ try{
+ mu = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -m, using default value " << mu << std::endl;
+ }
+ else if (std::string("-T") == argv[i])
+ try{
+ T = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -T, using default value " << T << std::endl;
+ }
+ else if (std::string("-t") == argv[i])
+ try{
+ TO = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -t, using default value " << TO << std::endl;
+ }
+ else if (std::string("-s") == argv[i])
+ try{
+ eventsSimulated = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -s, using default value " << eventsSimulated << std::endl;
+ }
+ else
+ {
+ std::cout << "invalid option \"" << argv[i] <<"\". To see valid options, run \"" << argv[0] << " -help\"" << std::endl;
+ }
+ }
+
+ /*std::cout << "checking values:\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n" << std::endl;
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n" << std::endl;*/
+
+
+
+
+ // Now the simulation can finally begin
+
+ hosts = new Host*[N]; // create an array to hold all Hosts
+ eventList = new GEL(); // create a list of events
+ Event* e; // holds the event currently being manipulated
+
+ // initialize static variables of events
+ Arrival::setLambda(lambda);
+ Departure::setMu(mu);
+ Sync::setSYNC(SYNC);
+ Host::initHosts(N, T);
+ Timeout::setTO(TO);
+
+
+ // initialize each host and create its initial arrival event
+ for (int i = 0; i < N; i++)
+ {
+ hosts[i] = new Host(i);
+ eventList->insert(new Arrival(time, i));
+
+ }
+
+ eventList->insert(new Sync(time)); // create the first sync event
+
+
+ for(int i = 0; i < eventsSimulated; i++)
+ {
+ // pop event to handle
+ e = eventList->removeFirst();
+
+ // update time
+ time = e->getEventTime();
+
+ if (e->getType() == arrival)
+ {
+ // cast to arrival pointer
+ Arrival *a = static_cast(e);
+
+ // check if cast actually worked
+ if (a)
+ {
+ // need to create a new arrival event for the previous arrival event's host
+ eventList->insert(new Arrival(time, a->getHost()));
+
+ // following line testing behaviour of arrival event
+ //std::cout << "process arrival event for host: " << a->getHost() << " at time: " << a->getEventTime() << std::endl;
+
+ // now need to put packet in queue of host.
+ // will generate length of packet on demand when create a departure event
+ // but need to indicate that it is not a ack packet
+ hosts[a->getHost()]->enqueueDataPacket(time);
+
+ }
+ else // not actually an arrival pointer
+ {
+ std::cerr << "error: process event of arrival type that wasn't actually an arrival event" << std::endl;
+ }
+ }
+
+
+ else if (e->getType() == departure)
+ {
+ // cast to departure pointer
+ Departure *d = static_cast(e);
+
+ // check if cast actually worked
+ if (d)
+ {
+ // keep track of bytes transmitted
+ transmitted += d->getSize();
+ packets ++;
+
+
+ // if an ack departure, need to notify receiving host
+ if (d->isAck())
+ {
+ // using an integer for packet IDs
+ hosts[d->getDestination()]->receiveAck(d->getPacketID());
+
+ }
+ // if a data departure, need to create ack packet in destination queue
+ else
+ {
+ hosts[d->getDestination()]->enqueueAckPacket(time, d->getSource(), d->getPacketID());
+ }
+ // set channel to free
+ channelBusy = false;
+
+
+ }
+ else // not actually a departure pointer
+ {
+ std::cerr << "error: process event of departure type that wasn't actually a departure event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == sync)
+ {
+ // cast to Sync pointer
+ Sync *s = static_cast(e);
+
+ // check if cast actually worked
+ if (s)
+ {
+ // need to create a new Sync event
+ eventList->insert(new Sync(time));
+
+ //std::cout << "process sync event at time: " << s->getEventTime() << std::endl;
+
+ // if channel is free, go through all hosts and decrement backoff.
+ // if backoff reaches zero, set channel to busy and create departure event
+ // also continue to decrement the rest of the backoffs to help with collision avoidance
+ if (channelBusy == false)
+ {
+ // possible host that needs to transmit
+ int hostToProcess = -1;
+ for (int i = 0; i < N; i++)
+ {
+ // decrements backoff value, returns true if backoff becomes zero
+ // need to save host index if it needs to be processed
+ // since we provide collision detection, there should only ever be one host ready to process
+ if(hosts[i]->decrementBackoff())
+ {
+ hostToProcess = i;
+ }
+
+ // if a host was selected to process, need to process it
+
+ }
+ if (hostToProcess >= 0)
+ {
+ // have the host create a departure event
+ Departure* departHelp = (hosts[hostToProcess]->createDeparture(time));
+ if (departHelp)
+ {
+ eventList->insert(departHelp);
+ // create a timeout event tied to the host, but only if not ack
+ if (!departHelp->isAck())
+ {
+ eventList->insert(hosts[hostToProcess]->createTimeout(time));
+
+ }
+ // set channel to busy
+ channelBusy = true;
+ }
+ }
+ }
+
+
+ }
+ else // not actually a sync pointer
+ {
+ std::cerr << "error: process event of sync type that wasn't actually a sync event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == timeout)
+ {
+ // cast to arrival pointer
+ Timeout *t = static_cast(e);
+
+ // check if actually worked
+ if (t)
+ {
+ // tell host that timeout event occured
+ hosts[t->getHost()]->receiveTimeout(time, t->getTimeoutID());
+
+ }
+ else // not actually a timeout pointer
+ {
+ std::cerr << "error: process event of timeout type that wasn't actually a timeout event" << std::endl;
+ }
+ }
+
+ // free memory of processed event
+ delete e;
+
+
+ }
+
+ int drop = 0;
+
+ for (int i = 0; i < N; i++)
+ {
+ delay += hosts[i]->getDelay();
+ drop += hosts[i]->getDropedPackets();
+ }
+
+ std::cout << "lambda: " << lambda << std::endl;
+ std::cout << "T: " << T << std::endl;
+ std::cout << "N: " << N << std::endl;
+
+ std::cout << "Throughput: " << transmitted / time << " Bps" << std::endl;
+ std::cout << "Average Network Delay: " << delay / transmitted << " s/B" << std::endl; // I changed this to make sense
+ // std::cout << "Average Network Delay: " << delay / packets << " s/packet" << std::endl; // I changed this to make sense
+ // std::cout << "Average Network Delay (per instructions): " << delay / (transmitted/time) << " s^2/B" << std::endl; // This is what doesn't make sense
+
+ std::cout << "Packets Dropped: " << drop << std::endl;
+ std::cout << "Packets Sent: " << packets << std::endl;
+
+ std::cout << "------------------------------------------------------" << std::endl;
+
+ // delete dynamically allocated data
+ for (int i = 0; i < N; i++)
+ {
+ delete hosts[i];
+ }
+ delete hosts;
+ delete eventList;
+
+}
\ No newline at end of file
diff --git a/hack.cpp b/hack.cpp
new file mode 100644
index 0000000..b916f10
--- /dev/null
+++ b/hack.cpp
@@ -0,0 +1,42 @@
+#include
+#include
+
+
+enum type
+{
+ arrival, departure, sync, timeout
+};
+
+class foo
+{
+public:
+ int lol;
+
+ foo()
+ {
+ lol = 10;
+ }
+};
+
+
+int main (int argc, const char** argv)
+{
+
+ type t;
+ t = departure;
+ std::cout << "type: " << t << std::endl;
+ int N = 10;
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ if (std::string("-N") == argv[i])
+ N = std::stoi(argv[i+1]);
+ }
+ std::cout << "N = " << N << std::endl;
+
+ foo* list = new foo[N];
+ for (int i = 0; i < N; i ++)
+ {
+ std::cout << list[i].lol << std::endl;
+ }
+
+}
\ No newline at end of file
diff --git a/hack2.cpp b/hack2.cpp
new file mode 100644
index 0000000..aa50ea8
--- /dev/null
+++ b/hack2.cpp
@@ -0,0 +1,44 @@
+#include
+#include
+
+
+enum type
+{
+ arrival, departure, sync, timeout
+};
+
+class foo
+{
+public:
+ int lol;
+
+ foo()
+ {
+ lol = 10;
+ }
+};
+
+
+int main (int argc, const char** argv)
+{
+
+ type t;
+ t = departure;
+ std::cout << "type: " << t << std::endl;
+ int N = 10;
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ if (std::string("-N") == argv[i])
+ N = std::stoi(argv[i+1]);
+ }
+ std::cout << "N = " << N << std::endl;
+
+ foo* list = new foo[N];
+ N = 10;
+ int list2[N];
+ for (int i = 0; i < N; i ++)
+ {
+ std::cout << list[i].lol << std::endl;
+ }
+
+}
\ No newline at end of file
diff --git a/hack3.cpp b/hack3.cpp
new file mode 100644
index 0000000..346067e
--- /dev/null
+++ b/hack3.cpp
@@ -0,0 +1,83 @@
+
+#include // random host
+
+#include
+
+using namespace std;
+
+int randomDestination(int source, int N)
+{
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, N - 1); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ rd = randomDestination(source, N);
+ }
+ return rd;
+}
+
+int generateRandomBackOff(int T, const int backoff[], int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(1, T); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+
+ // make sure the backoff value is not already given to another node
+ // this is for collision avoidance as the TA told us to do, even though
+ // it doesn't really happen in real life.
+ for (int i = 0; i < N; i++)
+ {
+ if (rd == backoff[i])
+ {
+ return generateRandomBackOff(T, backoff, N);
+ }
+ }
+ return rd;
+}
+
+
+int main(int argc, const char* argv[])
+{
+ int N, h, T;
+
+ cout << "enter nuber of hosts: " ;
+ cin >> N ;
+ cout << "enter maximum backoff: " ;
+ cin >> T ;
+
+ int data[N];
+ for (int i = 0; i < N; i++)
+ {
+ data[i] = -1;
+ }
+
+
+ while (true)
+ {
+ cout << "enter source host: " ;
+ cin >> h;
+ data[h] = 0;
+ data[h] = generateRandomBackOff(T, data, N);
+
+ for (int i = 0; i < N; i++){
+
+ cout << i << ": " << data[i] << endl;
+ }
+
+ }
+
+
+
+
+
+
+
+return 0;
+}
diff --git a/n.txt b/n.txt
new file mode 100644
index 0000000..0928128
--- /dev/null
+++ b/n.txt
@@ -0,0 +1,366 @@
+lambda: 0.01
+T: 20
+Throughput: 308.701 Bps
+Average Network Delay: 8.26926e-07 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 40
+Throughput: 31.8001 Bps
+Average Network Delay: 3.12177e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 80
+Throughput: 241.501 Bps
+Average Network Delay: 9.86634e-07 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 160
+Throughput: 122.1 Bps
+Average Network Delay: 1.92688e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 320
+Throughput: 97.6004 Bps
+Average Network Delay: 4.78762e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.01
+T: 400
+Throughput: 97.1004 Bps
+Average Network Delay: 4.78138e-06 s/B
+Packets Dropped: 0
+Packets Sent: 2
+------------------------------------------------------
+lambda: 0.05
+T: 20
+Throughput: 1279.03 Bps
+Average Network Delay: 8.88095e-07 s/B
+Average Network Delay: 0.000946561 s/packet
+Average Network Delay (per instructions): 8.88073e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 40
+Throughput: 849.72 Bps
+Average Network Delay: 1.14496e-06 s/B
+Average Network Delay: 0.000810727 s/packet
+Average Network Delay (per instructions): 1.14493e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 80
+Throughput: 812.92 Bps
+Average Network Delay: 1.42929e-06 s/B
+Average Network Delay: 0.000968227 s/packet
+Average Network Delay (per instructions): 1.42926e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 160
+Throughput: 950.123 Bps
+Average Network Delay: 1.69863e-06 s/B
+Average Network Delay: 0.00134489 s/packet
+Average Network Delay (per instructions): 1.69859e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 320
+Throughput: 1091.73 Bps
+Average Network Delay: 3.01445e-06 s/B
+Average Network Delay: 0.00274239 s/packet
+Average Network Delay (per instructions): 3.01438e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.05
+T: 400
+Throughput: 419.51 Bps
+Average Network Delay: 6.62425e-06 s/B
+Average Network Delay: 0.00231573 s/packet
+Average Network Delay (per instructions): 6.62409e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 12
+------------------------------------------------------
+lambda: 0.1
+T: 20
+Throughput: 2231.71 Bps
+Average Network Delay: 9.29801e-07 s/B
+Average Network Delay: 0.00086456 s/packet
+Average Network Delay (per instructions): 9.29756e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 40
+Throughput: 1513.97 Bps
+Average Network Delay: 1.19423e-06 s/B
+Average Network Delay: 0.00075331 s/packet
+Average Network Delay (per instructions): 1.19417e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 80
+Throughput: 1974.59 Bps
+Average Network Delay: 1.40083e-06 s/B
+Average Network Delay: 0.00115248 s/packet
+Average Network Delay (per instructions): 1.40076e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 160
+Throughput: 1723.88 Bps
+Average Network Delay: 1.99556e-06 s/B
+Average Network Delay: 0.00143331 s/packet
+Average Network Delay (per instructions): 1.99546e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 320
+Throughput: 2161.6 Bps
+Average Network Delay: 2.68931e-06 s/B
+Average Network Delay: 0.00242206 s/packet
+Average Network Delay (per instructions): 2.68918e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.1
+T: 400
+Throughput: 2001.2 Bps
+Average Network Delay: 3.08128e-06 s/B
+Average Network Delay: 0.00256914 s/packet
+Average Network Delay (per instructions): 3.08113e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 24
+------------------------------------------------------
+lambda: 0.3
+T: 20
+Throughput: 5703.78 Bps
+Average Network Delay: 9.20996e-07 s/B
+Average Network Delay: 0.000772418 s/packet
+Average Network Delay (per instructions): 9.20871e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 40
+Throughput: 6070.34 Bps
+Average Network Delay: 1.06254e-06 s/B
+Average Network Delay: 0.000921299 s/packet
+Average Network Delay (per instructions): 1.06239e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.3
+T: 80
+Throughput: 4687.34 Bps
+Average Network Delay: 1.40599e-06 s/B
+Average Network Delay: 0.000969035 s/packet
+Average Network Delay (per instructions): 1.4058e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 160
+Throughput: 3632.19 Bps
+Average Network Delay: 2.43176e-06 s/B
+Average Network Delay: 0.00129874 s/packet
+Average Network Delay (per instructions): 2.43143e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 68
+------------------------------------------------------
+lambda: 0.3
+T: 320
+Throughput: 6025.24 Bps
+Average Network Delay: 2.72344e-06 s/B
+Average Network Delay: 0.00234387 s/packet
+Average Network Delay (per instructions): 2.72306e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.3
+T: 400
+Throughput: 5730.1 Bps
+Average Network Delay: 3.0147e-06 s/B
+Average Network Delay: 0.00246744 s/packet
+Average Network Delay (per instructions): 3.01428e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 70
+------------------------------------------------------
+lambda: 0.6
+T: 20
+Throughput: 11168.7 Bps
+Average Network Delay: 9.5311e-07 s/B
+Average Network Delay: 0.000831432 s/packet
+Average Network Delay (per instructions): 9.52867e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 128
+------------------------------------------------------
+lambda: 0.6
+T: 40
+Throughput: 9911.4 Bps
+Average Network Delay: 1.10231e-06 s/B
+Average Network Delay: 0.000866879 s/packet
+Average Network Delay (per instructions): 1.10203e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 80
+Throughput: 10761 Bps
+Average Network Delay: 1.2735e-06 s/B
+Average Network Delay: 0.00108736 s/packet
+Average Network Delay (per instructions): 1.27318e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 160
+Throughput: 10981.2 Bps
+Average Network Delay: 1.78939e-06 s/B
+Average Network Delay: 0.0015591 s/packet
+Average Network Delay (per instructions): 1.78894e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 320
+Throughput: 8163.86 Bps
+Average Network Delay: 3.50556e-06 s/B
+Average Network Delay: 0.00227077 s/packet
+Average Network Delay (per instructions): 3.50468e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 126
+------------------------------------------------------
+lambda: 0.6
+T: 400
+Throughput: 10973.4 Bps
+Average Network Delay: 3.42795e-06 s/B
+Average Network Delay: 0.00280644 s/packet
+Average Network Delay (per instructions): 3.42704e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 134
+------------------------------------------------------
+lambda: 0.8
+T: 20
+Throughput: 14293.4 Bps
+Average Network Delay: 9.2127e-07 s/B
+Average Network Delay: 0.000792997 s/packet
+Average Network Delay (per instructions): 9.20965e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 40
+Throughput: 15190.9 Bps
+Average Network Delay: 1.03502e-06 s/B
+Average Network Delay: 0.000946853 s/packet
+Average Network Delay (per instructions): 1.03468e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 80
+Throughput: 11400.2 Bps
+Average Network Delay: 1.45895e-06 s/B
+Average Network Delay: 0.00100161 s/packet
+Average Network Delay (per instructions): 1.45846e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 160
+Throughput: 14805.4 Bps
+Average Network Delay: 1.81492e-06 s/B
+Average Network Delay: 0.00161818 s/packet
+Average Network Delay (per instructions): 1.81432e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.8
+T: 320
+Throughput: 14111.3 Bps
+Average Network Delay: 2.78043e-06 s/B
+Average Network Delay: 0.00233467 s/packet
+Average Network Delay (per instructions): 2.7795e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 168
+------------------------------------------------------
+lambda: 0.8
+T: 400
+Throughput: 13067.2 Bps
+Average Network Delay: 3.4313e-06 s/B
+Average Network Delay: 0.00270017 s/packet
+Average Network Delay (per instructions): 3.43016e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 166
+------------------------------------------------------
+lambda: 0.9
+T: 20
+Throughput: 14621.9 Bps
+Average Network Delay: 9.75482e-07 s/B
+Average Network Delay: 0.000774898 s/packet
+Average Network Delay (per instructions): 9.75125e-06 s^2/B
+Packets Dropped: 0
+Packets Sent: 184
+------------------------------------------------------
+lambda: 0.9
+T: 40
+Throughput: 15429.4 Bps
+Average Network Delay: 1.12303e-06 s/B
+Average Network Delay: 0.000951725 s/packet
+Average Network Delay (per instructions): 1.12262e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 80
+Throughput: 15956.5 Bps
+Average Network Delay: 1.29028e-06 s/B
+Average Network Delay: 0.00113082 s/packet
+Average Network Delay (per instructions): 1.28981e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 160
+Throughput: 13024.3 Bps
+Average Network Delay: 1.92281e-06 s/B
+Average Network Delay: 0.00139079 s/packet
+Average Network Delay (per instructions): 1.92211e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 180
+------------------------------------------------------
+lambda: 0.9
+T: 320
+Throughput: 14204.8 Bps
+Average Network Delay: 3.03224e-06 s/B
+Average Network Delay: 0.00236575 s/packet
+Average Network Delay (per instructions): 3.03114e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
+lambda: 0.9
+T: 400
+Throughput: 15867.7 Bps
+Average Network Delay: 3.1339e-06 s/B
+Average Network Delay: 0.0027313 s/packet
+Average Network Delay (per instructions): 3.13276e-05 s^2/B
+Packets Dropped: 0
+Packets Sent: 182
+------------------------------------------------------
diff --git a/nf.txt b/nf.txt
new file mode 100644
index 0000000..ff0911f
--- /dev/null
+++ b/nf.txt
@@ -0,0 +1,344 @@
+lambda: 0.01
+T: 20
+N: 20
+Throughput: 324.403 Bps
+Average Network Delay: 9.48658e-07 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.01
+T: 40
+N: 20
+Throughput: 124.401 Bps
+Average Network Delay: 1.46901e-06 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.01
+T: 80
+N: 20
+Throughput: 655.205 Bps
+Average Network Delay: 1.03593e-06 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.01
+T: 160
+N: 20
+Throughput: 180.601 Bps
+Average Network Delay: 2.82251e-06 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.01
+T: 320
+N: 20
+Throughput: 562.204 Bps
+Average Network Delay: 2.07532e-06 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.01
+T: 400
+N: 20
+Throughput: 476.204 Bps
+Average Network Delay: 2.61811e-06 s/B
+Packets Dropped: 0
+Packets Sent: 4
+------------------------------------------------------
+lambda: 0.05
+T: 20
+N: 20
+Throughput: 1928.3 Bps
+Average Network Delay: 9.58277e-07 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.05
+T: 40
+N: 20
+Throughput: 2054.61 Bps
+Average Network Delay: 1.0926e-06 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.05
+T: 80
+N: 20
+Throughput: 1296.57 Bps
+Average Network Delay: 1.54396e-06 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.05
+T: 160
+N: 20
+Throughput: 3187.57 Bps
+Average Network Delay: 1.40985e-06 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.05
+T: 320
+N: 20
+Throughput: 1706.69 Bps
+Average Network Delay: 3.32108e-06 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.05
+T: 400
+N: 20
+Throughput: 1821.69 Bps
+Average Network Delay: 3.29477e-06 s/B
+Packets Dropped: 0
+Packets Sent: 26
+------------------------------------------------------
+lambda: 0.1
+T: 20
+N: 20
+Throughput: 2974.27 Bps
+Average Network Delay: 1.00026e-06 s/B
+Packets Dropped: 0
+Packets Sent: 46
+------------------------------------------------------
+lambda: 0.1
+T: 40
+N: 20
+Throughput: 4197.99 Bps
+Average Network Delay: 1.02577e-06 s/B
+Packets Dropped: 0
+Packets Sent: 46
+------------------------------------------------------
+lambda: 0.1
+T: 80
+N: 20
+Throughput: 5602.42 Bps
+Average Network Delay: 1.25811e-06 s/B
+Packets Dropped: 0
+Packets Sent: 46
+------------------------------------------------------
+lambda: 0.1
+T: 160
+N: 20
+Throughput: 3982.27 Bps
+Average Network Delay: 1.83877e-06 s/B
+Packets Dropped: 0
+Packets Sent: 46
+------------------------------------------------------
+lambda: 0.1
+T: 320
+N: 20
+Throughput: 2989.98 Bps
+Average Network Delay: 3.31564e-06 s/B
+Packets Dropped: 0
+Packets Sent: 46
+------------------------------------------------------
+lambda: 0.1
+T: 400
+N: 20
+Throughput: 4996.87 Bps
+Average Network Delay: 2.47607e-06 s/B
+Packets Dropped: 0
+Packets Sent: 48
+------------------------------------------------------
+lambda: 0.3
+T: 20
+N: 20
+Throughput: 11980.9 Bps
+Average Network Delay: 9.52435e-07 s/B
+Packets Dropped: 0
+Packets Sent: 132
+------------------------------------------------------
+lambda: 0.3
+T: 40
+N: 20
+Throughput: 10134.3 Bps
+Average Network Delay: 1.10972e-06 s/B
+Packets Dropped: 0
+Packets Sent: 130
+------------------------------------------------------
+lambda: 0.3
+T: 80
+N: 20
+Throughput: 11760.3 Bps
+Average Network Delay: 1.31026e-06 s/B
+Packets Dropped: 0
+Packets Sent: 132
+------------------------------------------------------
+lambda: 0.3
+T: 160
+N: 20
+Throughput: 14024.6 Bps
+Average Network Delay: 1.69105e-06 s/B
+Packets Dropped: 0
+Packets Sent: 132
+------------------------------------------------------
+lambda: 0.3
+T: 320
+N: 20
+Throughput: 9396.27 Bps
+Average Network Delay: 3.05701e-06 s/B
+Packets Dropped: 0
+Packets Sent: 132
+------------------------------------------------------
+lambda: 0.3
+T: 400
+N: 20
+Throughput: 9222.6 Bps
+Average Network Delay: 3.59085e-06 s/B
+Packets Dropped: 0
+Packets Sent: 130
+------------------------------------------------------
+lambda: 0.6
+T: 20
+N: 20
+Throughput: 25848.1 Bps
+Average Network Delay: 9.40432e-07 s/B
+Packets Dropped: 0
+Packets Sent: 262
+------------------------------------------------------
+lambda: 0.6
+T: 40
+N: 20
+Throughput: 19069.9 Bps
+Average Network Delay: 1.11848e-06 s/B
+Packets Dropped: 0
+Packets Sent: 258
+------------------------------------------------------
+lambda: 0.6
+T: 60
+N: 20
+Throughput: 21546.9 Bps
+Average Network Delay: 1.22821e-06 s/B
+Packets Dropped: 0
+Packets Sent: 258
+------------------------------------------------------
+lambda: 0.6
+T: 80
+N: 20
+Throughput: 19665.9 Bps
+Average Network Delay: 1.39532e-06 s/B
+Packets Dropped: 0
+Packets Sent: 260
+------------------------------------------------------
+lambda: 0.6
+T: 160
+N: 20
+Throughput: 20026.2 Bps
+Average Network Delay: 1.87608e-06 s/B
+Packets Dropped: 0
+Packets Sent: 258
+------------------------------------------------------
+lambda: 0.6
+T: 320
+N: 20
+Throughput: 20723.6 Bps
+Average Network Delay: 2.9644e-06 s/B
+Packets Dropped: 0
+Packets Sent: 260
+------------------------------------------------------
+lambda: 0.6
+T: 400
+N: 20
+Throughput: 22169.4 Bps
+Average Network Delay: 3.19245e-06 s/B
+Packets Dropped: 0
+Packets Sent: 260
+------------------------------------------------------
+lambda: 0.8
+T: 20
+N: 20
+Throughput: 28142.1 Bps
+Average Network Delay: 1.00797e-06 s/B
+Packets Dropped: 0
+Packets Sent: 338
+------------------------------------------------------
+lambda: 0.8
+T: 40
+N: 20
+Throughput: 28994.4 Bps
+Average Network Delay: 1.12063e-06 s/B
+Packets Dropped: 0
+Packets Sent: 340
+------------------------------------------------------
+lambda: 0.8
+T: 80
+N: 20
+Throughput: 30957.9 Bps
+Average Network Delay: 1.32631e-06 s/B
+Packets Dropped: 0
+Packets Sent: 340
+------------------------------------------------------
+lambda: 0.8
+T: 160
+N: 20
+Throughput: 26638.7 Bps
+Average Network Delay: 1.88756e-06 s/B
+Packets Dropped: 0
+Packets Sent: 336
+------------------------------------------------------
+lambda: 0.8
+T: 320
+N: 20
+Throughput: 27409.5 Bps
+Average Network Delay: 2.96282e-06 s/B
+Packets Dropped: 0
+Packets Sent: 344
+------------------------------------------------------
+lambda: 0.8
+T: 400
+N: 20
+Throughput: 27276.6 Bps
+Average Network Delay: 3.37756e-06 s/B
+Packets Dropped: 0
+Packets Sent: 336
+------------------------------------------------------
+lambda: 0.9
+T: 20
+N: 20
+Throughput: 29464.3 Bps
+Average Network Delay: 9.70659e-07 s/B
+Packets Dropped: 0
+Packets Sent: 374
+------------------------------------------------------
+lambda: 0.9
+T: 40
+N: 20
+Throughput: 30951 Bps
+Average Network Delay: 1.10313e-06 s/B
+Packets Dropped: 0
+Packets Sent: 374
+------------------------------------------------------
+lambda: 0.9
+T: 80
+N: 20
+Throughput: 28762 Bps
+Average Network Delay: 1.38112e-06 s/B
+Packets Dropped: 0
+Packets Sent: 378
+------------------------------------------------------
+lambda: 0.9
+T: 160
+N: 20
+Throughput: 29654.2 Bps
+Average Network Delay: 1.80931e-06 s/B
+Packets Dropped: 0
+Packets Sent: 372
+------------------------------------------------------
+lambda: 0.9
+T: 320
+N: 20
+Throughput: 32499.1 Bps
+Average Network Delay: 2.6638e-06 s/B
+Packets Dropped: 0
+Packets Sent: 376
+------------------------------------------------------
+lambda: 0.9
+T: 400
+N: 20
+Throughput: 30616 Bps
+Average Network Delay: 3.2058e-06 s/B
+Packets Dropped: 0
+Packets Sent: 372
+------------------------------------------------------
diff --git a/simulator2.cpp b/simulator2.cpp
new file mode 100644
index 0000000..56b3759
--- /dev/null
+++ b/simulator2.cpp
@@ -0,0 +1,288 @@
+#include
+#include
+#include
+#include // max
+#include
+#include
+
+
+
+class Event {
+protected:
+ double eventTime;
+
+public:
+ Event(double etime): eventTime(etime) {}
+
+ double getEventTime() {
+ return eventTime;
+ }
+};
+
+class Arrival: public Event {
+
+};
+
+class Departure: public Event {
+
+};
+
+class Sync: public Event {
+
+};
+
+class Timeout: public Event{
+
+};
+
+
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list(); // this may not be necessary, but oh well
+ }
+
+ void insert(Event *event) {
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if ((*itr)->getEventTime() > event->getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ } // insert sorted by events time
+
+ Event* removeFirst() {
+
+ Event *firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+int main(int argc, char const *argv[])
+{
+// read from command line, but given default values
+ double lambda = 0.1; // dexcribes shape of arrival distribution
+ double mu = 1; // describes shape of distribution of PktSize (r)
+ int N = 10; // number of hosts in network.
+ int T = 400; // maximum backoff value in number sync cycles. Should be larger than N I suppose.
+ double timeout = 0.005; // for project, will take values of 5, 10, or 15 msec.
+
+// these should be constant for our project, but I'll define them here
+ double maxRTM = 3; // maximum number of retransmissions
+ int maxPktSize = 1544; // maximum size of a packet in bytes
+ int ackPktSize = 64; // acknowledgement packet size in bytes
+ double channelCapacity = 11000000.0; // 11 Mbps (bits)
+ double SIFS = 0.00005; // 0.05 msec, delay before ack
+ double DIFS = 0.0001; // 0.1 msec, delay before send
+ double SYNC = 0.00001; // 0.01 msec
+
+// these are variables used throught the program
+ double time = 0; // time simulated since start of simulation in seconds
+ double transmitted = 0; // number of bytes successfully transmitted (will include ack bytes)
+ double delay = 0; // queue + transmission delay in seconds
+
+ // check if help option set (or if only 1 argument, since that would be invalid).
+ // If so, print help information and end program
+ if ((argc > 1 && std::string("-help") == argv[1]) || argc == 2)
+ {
+ std::cout << "\nThis program simulates an IEEE 802.11-Based Wireless LAN. \n"
+ "To set parameters of network, use the following commands.\n"
+ "Default values are given in parenthesis.\n\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << timeout << "), given in msec\n" << std::endl;
+
+ return 0;
+ }
+
+ // read in command line inputs, assume all inputs come in a -var val pair
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ if (std::string("-N") == argv[i])
+ try{
+ N = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -N, using default value " << N << std::endl;
+ }
+ else if (std::string("-l") == argv[i])
+ try{
+ lambda = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -l, using default value " << lambda << std::endl;
+ }
+ else if (std::string("-m") == argv[i])
+ try{
+ mu = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -m, using default value " << mu << std::endl;
+ }
+ else if (std::string("-T") == argv[i])
+ try{
+ T = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -T, using default value " << T << std::endl;
+ }
+ else if (std::string("-t") == argv[i])
+ try{
+ timeout = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -t, using default value " << timeout << std::endl;
+ }
+ else
+ {
+ std::cout << "invalid option \"" << argv[i] <<"\". To see valid options, run \"" << argv[0] << " -help\"" << std::endl;
+ }
+ }
+
+ /*std::cout << "checking values:\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << timeout << "), given in msec\n" << std::endl;*/
+
+
+ // create an array of Hosts
+ Host* *hosts = new Host*[N];
+
+
+
+
+/*
+
+
+ Event e = Event(time + pareto(lambda), true);
+ GEL eventList = GEL();
+ eventList.insert(e);
+
+ //cerr << "hello 1" << endl;
+
+ // for 100000 events
+ // process event
+ // just going by the number given
+
+ for (int i = 0; i < 100000; i++)
+ {
+ // get closest event and update time
+ e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getIsArrival())
+ {
+ //cerr << "is Arrival, i: " << i << endl;
+ // insert new arrival event
+ eventList.insert(Event(time + pareto(lambda), true));
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ }
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}*/
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*std::log(1-u));
+}
+
diff --git a/weird.txt b/weird.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/weird.txt
@@ -0,0 +1 @@
+hello
diff --git a/wlan.cpp b/wlan.cpp
new file mode 100644
index 0000000..2b5583e
--- /dev/null
+++ b/wlan.cpp
@@ -0,0 +1,371 @@
+#include // random generators
+#include
+#include
+#include
+#include
+#include
+#include // max
+
+using namespace std;
+
+
+double nedt(double rate); // randomly calculates negative-exponenetially-distributed-time
+double generateRandomBackOff(double t);
+double randomDestination(int source);
+double dataLengthFrame(double rate);
+double transmissionTime(double r);
+
+class Packet {
+ int source;
+ int destination;
+ int packet_length;
+ bool isAck; // true acknowledgement, false datapacket
+
+public:
+ Packet(int s, int dest, int packet_bytes, bool ack) {
+ source = s;
+ destination = dest;
+ packet_length = packet_bytes;
+ isAck = ack;
+ }
+};
+
+class Host {
+public:
+ double backoff;
+ int hostId;
+ std::queue hostQueue;
+
+ Host();
+ Host(int id, double randomBackoffValue) {
+ backoff = randomBackoffValue;
+ hostQueue = std::queue();
+ hostId = id;
+ }
+
+ double getBackOff() {
+ return backoff;
+ }
+};
+
+enum eventtype {
+ arrival = 0, departure = 1, syncEvent = 2, timeout = 3
+};
+
+class Event {
+ double eventTime;
+ bool isArrival;
+ eventtype eventType;
+ int eventHostId;
+
+public:
+ Event(double etime, eventtype event, int hostId) {
+ eventTime = etime;
+ eventType = event;
+ eventHostId = hostId;
+ }
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ int getHost() {
+ return eventHostId;
+ }
+
+ // bool getIsArrival() {
+ // return arrival;
+ // }
+
+ eventtype getEventType() {
+ return eventType;
+ }
+
+ bool operator==(const Event &rhs) const {
+ return rhs.eventTime == eventTime;
+ }
+
+ bool operator>=(const Event &rhs) const {
+ return rhs.eventTime >= eventTime;
+ }
+
+ bool operator>(const Event &rhs) const {
+ return rhs.eventTime > eventTime;
+ }
+};
+
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list();
+ }
+
+ void insert(Event event) {
+
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if (itr->getEventTime() > event.getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+ } // insert sorted by events time
+
+ Event removeFirst() {
+
+ Event firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+
+int main(int argc, char const *argv[])
+{
+ // should be read in from command line
+ double lambda;
+ double mu;
+ double maxbuffer;
+ double sync;
+ double T;
+ double timeoutTime;
+ // double timeout; // 5 10 15
+
+ //std::cout << "lambda: ";
+ std::cin >> lambda;
+ //std::cout << "mu: ";
+ std::cin >> mu;
+ //std::cout << "Buffer Size: ";
+ std::cin >> maxbuffer;
+ std::cin >> sync;
+ std::cin >> T;
+ std::cin >> timeoutTime;
+
+ // variables
+ int length = 0;
+ int dropNum = 0;
+ double sumLength = 0;
+ double time = 0;
+ double busy = 0;
+ double packet = 0;
+
+ bool channelBusy = false; // false free, busy true
+ double r = 0; // data-length-frame
+ int N = 10;
+ int packetDestination = 0;
+ int packetTransmissionTime = 0;
+ int n = 0; // transmission count
+
+ int acknowledgementTime = 0;
+ int sendingTime = 0;
+ int sifs = .05 * pow(10, 3);
+ int difs = .1 * pow(10, 3);
+
+
+ // initalization
+ GEL eventList = GEL();
+
+ // Host *hosts = new Host[N];
+ std::vector hosts;
+
+ for (int i = 0; i < N; ++i)
+ {
+ hosts.push_back( Host(i, generateRandomBackOff(T)) );
+ }
+
+ for(int i = 0; i < N; i++)
+ {
+ eventList.insert(Event(time + nedt(lambda), arrival, i));
+ }
+ eventList.insert(Event(time + nedt(sync), syncEvent, -1)); // sync events do not have host, code -1
+
+ for (int i = 0; i < 100000; i++)
+ {
+ // get closest event and update time
+ Event e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getEventType() == arrival)
+ {
+ // generate new arrival event
+ eventList.insert(Event(time + nedt(lambda), arrival, e.getHost())); // arrival
+
+ r = dataLengthFrame(mu);
+
+ packetDestination = randomDestination(e.getHost());
+ Packet p = Packet(e.getHost(), packetDestination, r, false); // data packet for arrivals
+
+ // insert packet to queue
+ hosts[e.getHost()].hostQueue.push(p);
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0 || hosts[0].hostQueue.size() == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, departure, e.getHost())); // departure
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else if (e.getEventType() == departure)
+ {
+ channelBusy = false; // free the channel
+
+ packetDestination = randomDestination(e.getHost());
+ Packet ap = Packet(e.getHost(), packetDestination, 64, true); // acknowledgement packet for depatures
+
+ hosts[e.getHost()].hostQueue.push(ap);
+
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, departure, e.getHost())); // departure
+ }
+ }
+
+ else if (e.getEventType() == syncEvent)
+ {
+ // decreament counter for free channel
+ if (channelBusy == false) {
+
+ hosts[e.getHost()].backoff--;
+
+ if (hosts[e.getHost()].getBackOff() == 0) { // create departure event
+ eventList.insert(Event(time + packet, departure, e.getHost())); // departure event
+ channelBusy = true;
+
+ eventList.insert(Event(time + packet, timeout, e.getHost())); // timeout event while transmiting
+ hosts[e.getHost()].backoff = generateRandomBackOff(T); // generate new random backoff value
+ }
+ }
+
+ eventList.insert(Event(time + packet, syncEvent, e.getHost())); // next synchrinization event
+ sync += (.01 * pow(10, 3)); // msec to sec
+ }
+
+ else if (e.getEventType() == timeout)
+ {
+ eventList.insert(Event(time + timeout, departure, e.getHost())); // initial departure
+
+
+ acknowledgementTime = e.getEventTime() + transmissionTime(64) + sifs;
+ // sendingTime = time + transmissionTime(r) + difs;
+
+ // failed transmission : resend the packet, increase transmission count n
+ n++;
+ hosts[e.getHost()].backoff = generateRandomBackOff(T * n);
+ }
+
+ else {
+ cerr << "Error : event type is not known!";
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}
+
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*log(1-u));
+}
+
+double generateRandomBackOff(double t)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+ std::random_device rd; //Will be used to obtain a seed for the random number engine
+ std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
+ std::uniform_real_distribution<> dis(0, 1);
+ return int(t * dis(gen));
+}
+
+double randomDestination(int source)
+{
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, 9); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ rd = randomDestination(source);
+ }
+ return rd;
+}
+
+double dataLengthFrame(double rate)
+{
+ // http://en.cppreference.com/w/cpp/numeric/random/exponential_distribution
+ std::random_device rd;
+ std::mt19937 gen(rd());
+
+ std::exponential_distribution<> d(1); // generate nedt between 0 and 1
+
+ return int(1544 * d(gen));
+}
+
+double transmissionTime(double r)
+{
+ return (r * 8) / (11 * pow(10,6));
+}
\ No newline at end of file
diff --git a/wlan2.cpp b/wlan2.cpp
new file mode 100644
index 0000000..71beb52
--- /dev/null
+++ b/wlan2.cpp
@@ -0,0 +1,230 @@
+#include
+#include
+#include
+#include
+#include // max
+
+using namespace std;
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate);
+
+
+enum eventtype {
+ arrival = 0, departure = 1, syncEvent = 2, timeout = 3
+};
+
+class Event {
+ double eventTime;
+ bool isArrival; // type 0
+ // enum {
+ // arrival = 0, departure = 1, syncEvent = 2, timeout = 3
+ // } eventtype;
+ eventtype eventType;
+
+public:
+ Event(double etime, eventtype event) {
+ eventTime = etime;
+
+ eventType = event;
+ }
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ bool getIsArrival() {
+ return isArrival;
+ }
+
+ bool operator==(const Event &rhs) const {
+ return rhs.eventTime == eventTime;
+ }
+
+ bool operator>=(const Event &rhs) const {
+ return rhs.eventTime >= eventTime;
+ }
+
+ bool operator>(const Event &rhs) const {
+ return rhs.eventTime > eventTime;
+ }
+};
+
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list();
+ }
+ void insert(Event event) {
+ //cerr << "begin insert" << endl;
+
+ //cerr << "insert event.isArrival: " << event.getIsArrival() << endl;
+ //cerr << "size = " << GlobalEventList.size() << endl;
+
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if (itr->getEventTime() > event.getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ //cerr << "end insert " << endl;
+
+ } // insert sorted by events time
+
+ Event removeFirst() {
+
+ //cerr << "begin removeFirst" << endl;
+ Event firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ //cerr << "end removeFirst" << endl;
+
+ return firstElement;
+ }
+};
+
+int main(int argc, char const *argv[])
+{
+ // should be read in from command line
+ double lambda;
+ double mu;
+ double maxbuffer;
+ double sync;
+
+ //std::cout << "lambda: ";
+ std::cin >> lambda;
+
+ //std::cout << "mu: ";
+ std::cin >> mu;
+
+ //std::cout << "Buffer Size: ";
+ std::cin >> maxbuffer;
+
+ std::cin >> sync;
+
+ // variables
+ int length = 0;
+ int dropNum = 0;
+ double sumLength = 0;
+ double time = 0;
+ double busy = 0;
+ double packet = 0;
+ double r = 0; // data-length-frame
+
+ // initalization
+ GEL eventList = GEL();
+ for(int i = 0; i < 10; i++)
+ {
+ eventList.insert(Event(time + nedt(lambda), arrival));
+ }
+ // synchrinzation enum 2
+ eventList.insert(Event(time + nedt(sync), syncEvent));
+
+
+ for (int i = 0; i < 100000; i++)
+ {
+ // get closest event and update time
+ Event e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getIsArrival())
+ {
+ //cerr << "is Arrival, i: " << i << endl;
+ // insert new arrival event
+ eventList.insert(Event(time + nedt(lambda), arrival)); // arrival
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, departure)); // departure
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, departure)); // departure
+ }
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+
+
+ return 0;
+}
+
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*log(1-u));
+}
\ No newline at end of file
diff --git a/wlan3.cpp b/wlan3.cpp
new file mode 100644
index 0000000..c9a05fe
--- /dev/null
+++ b/wlan3.cpp
@@ -0,0 +1,326 @@
+#include // random host
+#include
+#include
+#include
+#include
+#include
+#include // max
+
+using namespace std;
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate);
+double generateRandomBackOff(double t);
+double randomDestination(int source);
+double dataLengthFrame(double rate);
+double transmissionTime(double r);
+
+class Packet {
+ int source;
+ int destination;
+ int packet_length;
+ bool isAck; // true acknowledgement, false datapacket
+
+public:
+ Packet(int s, int dest, int packet_bytes, bool ack) {
+ source = s;
+ destination = dest;
+ packet_length = packet_bytes;
+ isAck = ack;
+ }
+};
+
+class Host {
+ double backoff;
+ int hostId;
+ std::queue hostsQueue;
+
+public:
+ Host();
+ Host(int id, double randomBackoffValue) {
+ backoff = randomBackoffValue;
+ hostsQueue = std::queue();
+ hostId = id;
+ }
+
+ double getBackOff() {
+ return backoff;
+ }
+};
+
+enum eventtype {
+ arrival = 0, departure = 1, syncEvent = 2, timeout = 3
+};
+
+class Event {
+ double eventTime;
+ bool isArrival;
+ eventtype eventType;
+
+public:
+ Event(double etime, eventtype event) {
+ eventTime = etime;
+ eventType = event;
+ }
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ // bool getIsArrival() {
+ // return arrival;
+ // }
+
+ eventtype getEventType() {
+ return eventType;
+ }
+
+ bool operator==(const Event &rhs) const {
+ return rhs.eventTime == eventTime;
+ }
+
+ bool operator>=(const Event &rhs) const {
+ return rhs.eventTime >= eventTime;
+ }
+
+ bool operator>(const Event &rhs) const {
+ return rhs.eventTime > eventTime;
+ }
+};
+
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list();
+ }
+
+ void insert(Event event) {
+
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if (itr->getEventTime() > event.getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+ } // insert sorted by events time
+
+ Event removeFirst() {
+
+ //cerr << "begin removeFirst" << endl;
+ Event firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ //cerr << "end removeFirst" << endl;
+
+ return firstElement;
+ }
+};
+
+
+int main(int argc, char const *argv[])
+{
+ // should be read in from command line
+ double lambda;
+ double mu;
+ double maxbuffer;
+ double sync;
+ double T;
+
+ //std::cout << "lambda: ";
+ std::cin >> lambda;
+ //std::cout << "mu: ";
+ std::cin >> mu;
+ //std::cout << "Buffer Size: ";
+ std::cin >> maxbuffer;
+ std::cin >> sync;
+ std::cin >> T;
+
+ // variables
+ int length = 0;
+ int dropNum = 0;
+ double sumLength = 0;
+ double time = 0;
+ double busy = 0;
+ double packet = 0;
+
+ double r = 0; // data-length-frame
+ int N = 10;
+ int packetDestination = 0;
+ int packetTransmissionTime = 0;
+ // initalization
+ GEL eventList = GEL();
+ //Host *hosts = new Host[10];
+
+ Host h = Host(0, 3); // id index of hosts array
+ cout << h.getBackOff();
+
+ std::queue hostsQueue = std::queue();
+
+ // how to determine destination of packet? choose another random host
+ // 0 index in hosts array
+ packetDestination = randomDestination(1);
+ r = dataLengthFrame(mu);
+ Packet p = Packet(0, packetDestination, r, false);
+ hostsQueue.push(p);
+ packetTransmissionTime = transmissionTime(r);
+
+ for(int i = 0; i < N; i++)
+ {
+ eventList.insert(Event(time + nedt(lambda), arrival));
+ }
+ eventList.insert(Event(time + nedt(sync), syncEvent));
+
+
+ for (int i = 0; i < 100000; i++)
+ {
+ // get closest event and update time
+ Event e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getEventType() == arrival)
+ {
+ // generate new arrival event
+ eventList.insert(Event(time + nedt(lambda), arrival)); // arrival
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, departure)); // departure
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else if (e.getEventType() == departure)
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, departure)); // departure
+ }
+ }
+
+ else if (e.getEventType() == syncEvent)
+ {
+ eventList.insert(Event(time + packet, syncEvent));
+ }
+
+ else if (e.getEventType() == timeout)
+ {
+
+ }
+
+ else {
+ cerr << "Error : event type is not known!";
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}
+
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*log(1-u));
+}
+
+double generateRandomBackOff(double t)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+ std::random_device rd; //Will be used to obtain a seed for the random number engine
+ std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
+ std::uniform_real_distribution<> dis(0, 1);
+ return int(t * dis(gen));
+}
+
+double randomDestination(int source)
+{
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, 9); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ randomDestination(source); // should be rd = no?
+ }
+ return rd;
+}
+
+double dataLengthFrame(double rate)
+{
+ // how? multiple by 1544 and round integer after calling nedt?
+ // what is this time? for 1544 byte packet, (1544 × 8) / (11 × 106) = 1.12 msec
+
+ return int(1544 * nedt(rate)); // prob wrong [0, 1544]
+}
+
+double transmissionTime(double r)
+{
+ return (r * 8) / (11 * pow(10,6));
+}
\ No newline at end of file
diff --git a/wlanAllen.cpp b/wlanAllen.cpp
new file mode 100644
index 0000000..85e3467
--- /dev/null
+++ b/wlanAllen.cpp
@@ -0,0 +1,383 @@
+#include
+#include
+#include
+#include
+#include // max
+#include
+#include
+
+
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*std::log(1-u));
+}
+
+
+enum eventtype {
+ arrival, departure, syncEvent, timeout
+};
+
+class Event {
+protected:
+ double eventTime;
+ eventtype type;
+ int source;
+ int dest;
+
+public:
+ Event(double etime, eventtype type): eventTime(etime), type(type) {}
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ eventtype getType()
+ {
+ return type;
+ }
+};
+
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list(); // this line may not be necessary, but oh well
+ }
+
+ void insert(Event *event) {
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if ((*itr)->getEventTime() > event->getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ } // insert sorted by events time
+
+ Event* removeFirst() {
+
+ Event *firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+// not sure i need all this stuff yet
+class Packet {
+ int source;
+ int destination;
+ int packet_length;
+ bool isAck; // true acknowledgement, false datapacket
+
+public:
+ Packet(int s, int dest, int packet_bytes, bool ack) {
+ source = s;
+ destination = dest;
+ packet_length = packet_bytes;
+ isAck = ack;
+ }
+};
+
+class Host {
+ int backoff; // doing it in syc tics versus real time because easier for conflict avoidance
+ int hostId; // position in hosts array, maybe don't need this, but might if put create packets and stuff
+ int tmNum; // transmission number, max tmNum = 1 + maxRTM. Max backoff = tmNum * T
+ std::queue hostsQueue;
+
+public:
+ Host(){};
+ Host(int id, double randomBackoffValue) {
+ backoff = randomBackoffValue;
+ hostsQueue = std::queue();
+ hostId = id;
+ tmNum = 1;
+ }
+
+ double getBackOff() {
+ return backoff;
+ }
+};
+
+
+
+int main(int argc, char const *argv[])
+{
+
+// read from command line, but given default values
+ double lambda = 0.1; // dexcribes shape of arrival distribution
+ double mu = 1; // describes shape of distribution of PktSize (r)
+ int N = 10; // number of hosts in network.
+ int T = 400; // maximum backoff value in number sync cycles. Should be larger than N I suppose.
+ double timeout = 0.005; // for project, will take values of 5, 10, or 15 msec.
+ int eventsSimulated = 100000; // the bound of for loop
+
+// these should be constant for our project, but I'll define them here
+ double maxRTM = 3; // maximum number of retransmissions
+ int maxPktSize = 1544; // maximum size of a packet in bytes
+ int ackPktSize = 64; // acknowledgement packet size in bytes
+ double channelCapacity = 11000000.0; // 11 Mbps (bits)
+ double SIFS = 0.00005; // 0.05 msec, delay before ack
+ double DIFS = 0.0001; // 0.1 msec, delay before send
+ double SYNC = 0.00001; // 0.01 msec
+
+// these are variables used throught the program
+ double time = 0; // time simulated since start of simulation in seconds
+ double transmitted = 0; // number of bytes successfully transmitted (will include ack bytes)
+ double delay = 0; // queue + transmission delay in seconds
+ bool channelBusy = false; // true if channel is busy, false otherwise
+
+// containers
+ Host* *hosts; // an array of host pointers
+ GEL* eventList; // holds list of events
+
+ // check if help option set (or if only 1 argument, since that would be invalid).
+ // If so, print help information and end program
+ if ((argc > 1 && std::string("-help") == argv[1]) || argc == 2)
+ {
+ std::cout << "\nThis program simulates an IEEE 802.11-Based Wireless LAN. \n"
+ "To set parameters of network, use the following commands.\n"
+ "Default values are given in parenthesis.\n\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << timeout << "), given in msec\n"
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n"<< std::endl;
+
+ return 0;
+ }
+
+ // read in command line inputs, assume all inputs come in a -var val pair
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ // i probably should have made this a function, but i already did the copy paste so really no use now
+ if (std::string("-N") == argv[i])
+ try{
+ N = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -N, using default value " << N << std::endl;
+ }
+ else if (std::string("-l") == argv[i])
+ try{
+ lambda = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -l, using default value " << lambda << std::endl;
+ }
+ else if (std::string("-m") == argv[i])
+ try{
+ mu = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -m, using default value " << mu << std::endl;
+ }
+ else if (std::string("-T") == argv[i])
+ try{
+ T = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -T, using default value " << T << std::endl;
+ }
+ else if (std::string("-t") == argv[i])
+ try{
+ timeout = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -t, using default value " << timeout << std::endl;
+ }
+ else if (std::string("-s") == argv[i])
+ try{
+ eventsSimulated = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -s, using default value " << eventsSimulated << std::endl;
+ }
+ else
+ {
+ std::cout << "invalid option \"" << argv[i] <<"\". To see valid options, run \"" << argv[0] << " -help\"" << std::endl;
+ }
+ }
+
+ /*std::cout << "checking values:\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << timeout << "), given in msec\n" << std::endl;
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n" << std::endl;*/
+
+
+
+
+ // Now the simulation can finally begin
+
+ hosts = new Host*[N]; // create an array to hold all Hosts
+ eventList = new GEL(); // create a list of events
+
+
+ // initialize each host and create its initial arrival event
+ for (int i = 0; i < N; i++)
+ {
+ hosts[i] = new Host();
+ eventList->insert(new Arrival(time + nedt(lambda), i));
+
+ }
+
+ eventList->insert(new Sync(time + SYNC)); // create the first sync event
+
+
+ for(int i = 0; i < eventsSimulated; i++)
+ {
+ Event* e = eventList->removeFirst();
+
+
+ }
+
+
+
+
+ // delete dynamically allocated data
+ for (int i = 0; i < N; i++)
+ {
+ delete hosts[i];
+ }
+ delete hosts;
+ delete eventList;
+
+
+
+}
+
+
+
+
+/*
+
+
+ Event e = Event(time + pareto(lambda), true);
+ GEL eventList = GEL();
+ eventList.insert(e);
+
+ //cerr << "hello 1" << endl;
+
+ // for 100000 events
+ // process event
+ // just going by the number given
+
+ for (int i = 0; i < eventsSimulated; i++)
+ {
+ // get closest event and update time
+ e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getIsArrival())
+ {
+ //cerr << "is Arrival, i: " << i << endl;
+ // insert new arrival event
+ eventList.insert(Event(time + pareto(lambda), true));
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ }
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}*/
+
+
+
diff --git a/wlanAllen2.cpp b/wlanAllen2.cpp
new file mode 100644
index 0000000..fe80d3c
--- /dev/null
+++ b/wlanAllen2.cpp
@@ -0,0 +1,939 @@
+#include
+#include
+#include
+#include
+#include // max
+#include
+#include
+#include // for hooman random stuff
+
+
+// these should be constant for our project
+ const double maxRTM = 3; // maximum number of retransmissions
+ const int maxPktSize = 1544; // maximum size of a packet in bytes
+ const int ackPktSize = 64; // acknowledgement packet size in bytes
+ const double channelCapacity = 11000000.0; // 11 Mbps (bits)
+ const double SIFS = 0.00005; // 0.05 msec, delay before ack
+ const double DIFS = 0.0001; // 0.1 msec, delay before send
+ const double SYNC = 0.00001; // 0.01 msec
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*std::log(1-u));
+}
+
+double dataLengthFrame(double rate)
+{
+ // http://en.cppreference.com/w/cpp/numeric/random/exponential_distribution
+ std::random_device rd;
+ std::mt19937 gen(rd());
+
+ std::exponential_distribution<> d(1); // generate nedt between 0 and 1
+
+ return int(maxPktSize * d(gen));
+}
+
+double transmissionTime(int bytes)
+{
+ return (bytes * 8) / (channelCapacity);
+}
+
+// generate a random backoff value less than or equal to T that is not currently in the backoff list
+int generateRandomBackOff(int T, const int backoff[], int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(1, T); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+
+ // make sure the backoff value is not already given to another node
+ // this is for collision avoidance as the TA told us to do, even though
+ // it doesn't really happen in real life.
+ for (int i = 0; i < N; i++)
+ {
+ if (rd == backoff[i])
+ {
+ return generateRandomBackOff(T, backoff, N);
+ }
+ }
+ return rd;
+}
+
+int randomDestination(int source, int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, N - 1); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ rd = randomDestination(source, N);
+ }
+ return rd;
+}
+
+enum eventtype {
+ arrival, departure, sync, timeout
+};
+
+
+class Event {
+protected:
+ double eventTime;
+ eventtype type;
+
+
+public:
+ Event(eventtype type, double etime): eventTime(etime), type(type) {}
+ virtual ~Event(){}
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ eventtype getType()
+ {
+ return type;
+ }
+
+};
+
+class Arrival: public Event {
+ static double lambda;
+
+ int host;
+
+public:
+ Arrival(double stime, int h): Event(arrival, stime + nedt(lambda)), host(h) {}
+
+ static void setLambda(double l)
+ {
+ lambda = l;
+ }
+
+ int getHost()
+ {
+ return host;
+ }
+
+};
+
+double Arrival::lambda = 0;
+
+class Departure: public Event {
+
+ // shape of packet size distribution
+ static double mu;
+
+ bool ack; // denotes if it is an acknowedgement packet
+ int source; // source host
+ int destination; // destination host
+ int packetID; // id of packet, see host class
+ int size; // paket size in bytes, used to determine throughput
+
+public:
+ Departure(double stime, int s, int d, int id, bool a): Event(departure, stime), ack(a), source(s), destination(d), packetID(id)
+ {
+ // if ack packet, set the time to be that size
+ // time already current time, so just need to add the new time.
+ if(ack)
+ {
+ // this shouldn't be how it works in real life
+ // we're supposed to scan the channel during sifs,
+ // then if clear set channel to busy and transmit.
+ // For this project TA say just add SIFS, which is easier so OK then
+ size = ackPktSize;
+ eventTime += (SIFS + transmissionTime(size));
+ }
+ else
+ {
+ // same comment as above, except DFIS
+ size = dataLengthFrame(mu);
+ eventTime += (DIFS + transmissionTime(size));
+
+ }
+
+ }
+
+ static void setMu(double m)
+ {
+ mu = m;
+ }
+
+ bool isAck()
+ {
+ return ack;
+ }
+
+ int getSource()
+ {
+ return source;
+ }
+ int getDestination()
+ {
+ return destination;
+ }
+ int getPacketID()
+ {
+ return packetID;
+ }
+ int getSize()
+ {
+ return size;
+ }
+
+
+};
+
+double Departure::mu = 0;
+
+class Sync: public Event {
+
+ static double SYNC;
+
+public:
+ Sync(double stime): Event(sync, stime + SYNC) {}
+
+ static void setSYNC(double s)
+ {
+ SYNC = s;
+ }
+
+};
+
+double Sync::SYNC = 0;
+
+class Timeout: public Event{
+
+ static double to_time;
+
+ int host;
+ int timeoutID;
+public:
+ Timeout(double stime, int h, int id): Event(timeout, stime + to_time), host(h), timeoutID(id) {}
+
+ static void setTO(double t)
+ {
+ to_time = t;
+ }
+
+
+ int getHost()
+ {
+ return host;
+ }
+
+ int getTimeoutID()
+ {
+ return timeoutID;
+ }
+
+};
+
+double Timeout::to_time = 0;
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list(); // this line may not be necessary, but oh well
+ }
+
+ void insert(Event *event) {
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if ((*itr)->getEventTime() > event->getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ } // insert sorted by events time
+
+ Event* removeFirst() {
+
+ Event *firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+// not sure i need all this stuff yet
+class Packet {
+ int destination;
+ bool isAck; // true acknowledgement, false datapacket
+ int ackID; // used to make sure ack makes sense and stuff
+ double queueTime; // time when packet first queued, used for statistics (Network delay)
+
+
+ friend class Host;
+
+public:
+ Packet(double t, int dest, bool ack, int id = 0): destination(dest), isAck(ack), ackID(id), queueTime(t){}
+
+
+};
+
+class Host {
+ static int NumHosts; // need to know this in order to create random destination
+ static int T; // maximum backoff given no retransmissions
+ // static array so we can implement collision avoidance
+ static int* backoff; // doing it in syc tics versus real time because easier for conflict avoidance
+ // backoff < 0 means nothing in queue (nothing to transmit)
+ // backoff > 0 means waiting to transmit
+ // backoff == 0 means either transmitting or waiting for ack
+
+ int packetID; // the number of the packet sent.
+ // Not worring about overflow, and even it it does, it should still work correctly.
+ // Used to cordinate acks and timeouts.
+ // If a timeout occurs, there's a chance that there will be acks in the network
+ // that don't refer to the most recent transmission.
+
+ int droppedPackets; // not necessary for our project, but i think it might be interesting to keep track of
+ int hostID; // position in hosts array, maybe don't need this, but might if put create packets and stuff
+ int tmNum; // transmission number, max tmNum = 1 + maxRTM. Max backoff = tmNum * T
+
+ double retransmitTime; // used to calculate delay when there has been a retransmission
+ double delay; // total delay, used for statistics.
+ std::queue packetQueue; // i think its initialized implicitly
+
+public:
+ // initially set backoff to (-1) to show that nothing in queue
+ Host(int id): packetID(0), droppedPackets(0), hostID(id), tmNum(0), retransmitTime(0), delay(0){
+ backoff[id] = -1;
+ }
+
+ // initialize static variables
+ static void initHosts(int N, int t)
+ {
+ NumHosts = N;
+ backoff = new int[N];
+ T = t;
+ }
+
+ double getDelay()
+ {
+ return delay;
+ }
+
+ int getDropedPackets()
+ {
+ return droppedPackets;
+ }
+
+ void enqueueDataPacket(double stime)
+ {
+ packetQueue.push(Packet(stime, randomDestination(hostID, NumHosts), false));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet.
+ // in real life I don't think the first packet waits for a backoff,
+ // but the TAs told us to do it this way.
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+ void enqueueAckPacket(double stime, int dest, int ackID)
+ {
+
+ // In real life I don't think the ack goes in the back of the queue,
+ // But the TAs told us to do it this way.
+
+ packetQueue.push(Packet(stime, dest, true, ackID));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+
+ }
+
+ // decrements backoff value if it is larger than zero
+ // returns true if this act makes the value 0, and thus the Host is ready to transmit
+ bool decrementBackoff()
+ {
+ if (backoff[hostID] > 0)
+ {
+ --(backoff[hostID]);
+ if(backoff[hostID] == 0)
+ return true;
+ }
+ return false;
+ }
+
+
+ void receiveAck(int AckID)
+ {
+ // if correct ack, can pop packet from start of queue
+ if (AckID == packetID)
+ {
+ packetQueue.pop(); // pop packet from queue
+ packetID++; // new packet to send, so increment packetID
+ tmNum = 0; // need to reset TmNum because new packet to transmit.
+ // if no more packets in queue, indicate it by setting backoff id to -1
+ if (packetQueue.empty())
+ {
+ backoff[hostID] = -1;
+ }
+ // eles if still packet to send, set new backoff value
+ else
+ {
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+
+
+ }
+ // if AckID does not match PacketID do nothing
+ // should never get out of order ack because can only sent 1 packet at a time
+ }
+
+ void receiveTimeout(double stime, int TO_ID)
+ {
+ // if timeout refers to current packet, need to resend with larger backoff
+ if (TO_ID == packetID)
+ {
+ // if haven't reached maximum transmissions yet, need to retransmit it by resetting backoff value
+ // tmNum refers to current transmission. On transmission 3, there have been 2 retransmissions
+ // if MaxRTM = 3, then should be able to send another one.
+ // if MaxRTM = 3 and tmNum = 4, then there have already been 3 retransmissions and need to abort
+ if (tmNum <= maxRTM)
+ {
+ // need to reset packet queue time because should not double count delay when waiting for ack
+ // actually, i don't want to make it a queue of pointers so i'll do this hack instead
+ retransmitTime = stime;
+
+ // need to increase mack backoff by a multiple of (tmNum + 1),
+ // since tmNum in incremented when departure event created, but need to use that as a multiplyer here
+ backoff[hostID] = generateRandomBackOff(T * (tmNum + 1), backoff, NumHosts);
+ }
+ // else need to drop packet. Do this by pretending to ack it
+ else
+ {
+ droppedPackets++;
+ receiveAck(packetID);
+
+ }
+
+ }
+
+ }
+
+
+ // performs packet processing and prepares packet for departure
+ // returns a departure event
+ // not going to do error checking, so assumes that there is at least 1 packet in the queue and that hopeufully backoff == 0
+ // actually, maybe will do error checking
+ Departure* createDeparture(double stime)
+ {
+ // i lied, error checking
+ if (backoff[hostID] != 0)
+ std::cerr << "Host creating Departure event when backoff != 0" << std::endl;
+ // the other one should cause runtime issues if bug, so won't check for it
+ // no that's stupid
+ if (packetQueue.empty())
+ {
+ std::cerr << "Host creating Departure event when queue empty" << std::endl;
+
+ return NULL;
+ }
+
+
+
+ // get packet info
+ Packet p = packetQueue.front();
+
+ Departure* depart; // holds return value
+
+
+ //std::cerr << "creating departure with destination: " << p.destination << std::endl;
+
+ // if an ack packet, create ack event
+ // since we don't need to wait for ack, can immediatley pretend we got one
+ if (p.isAck)
+ {
+ receiveAck(packetID);
+ depart = new Departure(stime, hostID, p.destination, p.ackID, true);
+ }
+ // else need to create packet and increment tmNum
+ else
+ {
+ tmNum ++;
+ depart = new Departure(stime, hostID, p.destination, hostID, false);
+
+ }
+
+ // calculate delay
+ // if this is a retransmission (tmNum > 1), then need to use retransmitTime as a base
+ if (tmNum > 1)
+ {
+ delay += (depart->getEventTime() - retransmitTime);
+ }
+ // else use packet time as a base
+ else
+ {
+ delay += (depart->getEventTime() - p.queueTime);
+ }
+
+ return depart;
+
+ }
+
+ Timeout* createTimeout(double stime)
+ {
+ return new Timeout(stime, hostID, packetID);
+ }
+
+};
+
+int* Host::backoff = NULL;
+int Host::NumHosts = 0;
+int Host::T = 0;
+
+
+
+int main(int argc, char const *argv[])
+{
+
+// read from command line, but given default values
+ double lambda = 0.1; // dexcribes shape of arrival distribution
+ double mu = 1; // describes shape of distribution of PktSize (r)
+ int N = 10; // number of hosts in network.
+ int T = 400; // maximum backoff value in number sync cycles. Should be larger than N I suppose.
+ double TO = 0.005; // for project, will take values of 5, 10, or 15 msec.
+ int eventsSimulated = 100000; // the bound of for loop
+
+// these are variables used throught the program
+ double time = 0; // time simulated since start of simulation in seconds
+ double transmitted = 0; // number of bytes successfully transmitted (will include ack bytes)
+ double delay = 0; // queue + transmission delay in seconds
+ int packets = 0;
+ bool channelBusy = false; // true if channel is busy, false otherwise
+
+// containers
+ Host* *hosts; // an array of host pointers
+ GEL* eventList; // holds list of events
+
+ // check if help option set (or if only 1 argument, since that would be invalid).
+ // If so, print help information and end program
+ if ((argc > 1 && std::string("-help") == argv[1]) || argc == 2)
+ {
+ std::cout << "\nThis program simulates an IEEE 802.11-Based Wireless LAN. \n"
+ "To set parameters of network, use the following commands.\n"
+ "Default values are given in parenthesis.\n\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n"
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n"<< std::endl;
+
+ return 0;
+ }
+
+ // read in command line inputs, assume all inputs come in a -var val pair
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ // i probably should have made this a function, but i already did the copy paste so really no use now
+ if (std::string("-N") == argv[i])
+ try{
+ N = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -N, using default value " << N << std::endl;
+ }
+ else if (std::string("-l") == argv[i])
+ try{
+ lambda = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -l, using default value " << lambda << std::endl;
+ }
+ else if (std::string("-m") == argv[i])
+ try{
+ mu = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -m, using default value " << mu << std::endl;
+ }
+ else if (std::string("-T") == argv[i])
+ try{
+ T = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -T, using default value " << T << std::endl;
+ }
+ else if (std::string("-t") == argv[i])
+ try{
+ TO = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -t, using default value " << TO << std::endl;
+ }
+ else if (std::string("-s") == argv[i])
+ try{
+ eventsSimulated = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -s, using default value " << eventsSimulated << std::endl;
+ }
+ else
+ {
+ std::cout << "invalid option \"" << argv[i] <<"\". To see valid options, run \"" << argv[0] << " -help\"" << std::endl;
+ }
+ }
+
+ /*std::cout << "checking values:\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n" << std::endl;
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n" << std::endl;*/
+
+
+
+
+ // Now the simulation can finally begin
+
+ hosts = new Host*[N]; // create an array to hold all Hosts
+ eventList = new GEL(); // create a list of events
+ Event* e; // holds the event currently being manipulated
+
+ // initialize static variables of events
+ Arrival::setLambda(lambda);
+ Departure::setMu(mu);
+ Sync::setSYNC(SYNC);
+ Host::initHosts(N, T);
+ Timeout::setTO(TO);
+
+
+ // initialize each host and create its initial arrival event
+ for (int i = 0; i < N; i++)
+ {
+ hosts[i] = new Host(i);
+ eventList->insert(new Arrival(time, i));
+
+ }
+
+ eventList->insert(new Sync(time)); // create the first sync event
+
+
+ for(int i = 0; i < eventsSimulated; i++)
+ {
+ // pop event to handle
+ e = eventList->removeFirst();
+
+ // update time
+ time = e->getEventTime();
+
+ if (e->getType() == arrival)
+ {
+ // cast to arrival pointer
+ Arrival *a = static_cast(e);
+
+ // check if cast actually worked
+ if (a)
+ {
+ // need to create a new arrival event for the previous arrival event's host
+ eventList->insert(new Arrival(time, a->getHost()));
+
+ // following line testing behaviour of arrival event
+ //std::cout << "process arrival event for host: " << a->getHost() << " at time: " << a->getEventTime() << std::endl;
+
+ // now need to put packet in queue of host.
+ // will generate length of packet on demand when create a departure event
+ // but need to indicate that it is not a ack packet
+ hosts[a->getHost()]->enqueueDataPacket(time);
+
+ }
+ else // not actually an arrival pointer
+ {
+ std::cerr << "error: process event of arrival type that wasn't actually an arrival event" << std::endl;
+ }
+ }
+
+
+ else if (e->getType() == departure)
+ {
+ // cast to departure pointer
+ Departure *d = static_cast(e);
+
+ // check if cast actually worked
+ if (d)
+ {
+ // keep track of bytes transmitted
+ transmitted += d->getSize();
+ packets ++;
+
+
+ // if an ack departure, need to notify receiving host
+ if (d->isAck())
+ {
+ // using an integer for packet IDs
+ hosts[d->getDestination()]->receiveAck(d->getPacketID());
+
+ }
+ // if a data departure, need to create ack packet in destination queue
+ else
+ {
+ hosts[d->getDestination()]->enqueueAckPacket(time, d->getSource(), d->getPacketID());
+ }
+ // set channel to free
+ channelBusy = false;
+
+
+ }
+ else // not actually a departure pointer
+ {
+ std::cerr << "error: process event of departure type that wasn't actually a departure event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == sync)
+ {
+ // cast to Sync pointer
+ Sync *s = static_cast(e);
+
+ // check if cast actually worked
+ if (s)
+ {
+ // need to create a new Sync event
+ eventList->insert(new Sync(time));
+
+ //std::cout << "process sync event at time: " << s->getEventTime() << std::endl;
+
+ // if channel is free, go through all hosts and decrement backoff.
+ // if backoff reaches zero, set channel to busy and create departure event
+ // also continue to decrement the rest of the backoffs to help with collision avoidance
+ if (channelBusy == false)
+ {
+ // possible host that needs to transmit
+ int hostToProcess = -1;
+ for (int i = 0; i < N; i++)
+ {
+ // decrements backoff value, returns true if backoff becomes zero
+ // need to save host index if it needs to be processed
+ // since we provide collision detection, there should only ever be one host ready to process
+ if(hosts[i]->decrementBackoff())
+ {
+ hostToProcess = i;
+ }
+
+ // if a host was selected to process, need to process it
+
+ }
+ if (hostToProcess >= 0)
+ {
+ // have the host create a departure event
+ Departure* departHelp = (hosts[hostToProcess]->createDeparture(time));
+ if (departHelp)
+ {
+ eventList->insert(departHelp);
+ // create a timeout event tied to the host, but only if not ack
+ if (!departHelp->isAck())
+ {
+ eventList->insert(hosts[hostToProcess]->createTimeout(time));
+
+ }
+ // set channel to busy
+ channelBusy = true;
+ }
+ }
+ }
+
+
+ }
+ else // not actually a sync pointer
+ {
+ std::cerr << "error: process event of sync type that wasn't actually a sync event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == timeout)
+ {
+ // cast to arrival pointer
+ Timeout *t = static_cast(e);
+
+ // check if actually worked
+ if (t)
+ {
+ // tell host that timeout event occured
+ hosts[t->getHost()]->receiveTimeout(time, t->getTimeoutID());
+
+ }
+ else // not actually a timeout pointer
+ {
+ std::cerr << "error: process event of timeout type that wasn't actually a timeout event" << std::endl;
+ }
+ }
+
+ // free memory of processed event
+ delete e;
+
+
+ }
+
+
+
+ int drop = 0;
+
+ for (int i = 0; i < N; i++)
+ {
+ delay += hosts[i]->getDelay();
+ drop += hosts[i]->getDropedPackets();
+ }
+
+
+ std::cout << "Throughput: " << transmitted / time << " Bps" << std::endl;
+ std::cout << "Average Network Delay: " << delay / transmitted << " s/B" << std::endl; // I changed this to make sense
+ std::cout << "Average Network Delay: " << delay / packets << " s/packet" << std::endl; // I changed this to make sense
+ std::cout << "Average Network Delay (per instructions): " << delay / (transmitted/time) << " s^2/B" << std::endl; // This is what doesn't make sense
+
+ std::cout << "Packets Dropped: " << drop << std::endl;
+
+
+
+ // delete dynamically allocated data
+ for (int i = 0; i < N; i++)
+ {
+ delete hosts[i];
+ }
+ delete hosts;
+ delete eventList;
+
+
+
+}
+
+
+
+
+/*
+
+
+ Event e = Event(time + pareto(lambda), true);
+ GEL eventList = GEL();
+ eventList.insert(e);
+
+ //cerr << "hello 1" << endl;
+
+ // for 100000 events
+ // process event
+ // just going by the number given
+
+ for (int i = 0; i < eventsSimulated; i++)
+ {
+ // get closest event and update time
+ e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getIsArrival())
+ {
+ //cerr << "is Arrival, i: " << i << endl;
+ // insert new arrival event
+ eventList.insert(Event(time + pareto(lambda), true));
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ }
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}*/
+
+
+
diff --git a/wlanAllen3.cpp b/wlanAllen3.cpp
new file mode 100644
index 0000000..05911e9
--- /dev/null
+++ b/wlanAllen3.cpp
@@ -0,0 +1,942 @@
+#include
+#include
+#include
+#include
+#include // max
+#include
+#include
+#include // for hooman random stuff
+
+
+// these should be constant for our project
+ const double maxRTM = 3; // maximum number of retransmissions
+ const int maxPktSize = 1544; // maximum size of a packet in bytes
+ const int ackPktSize = 64; // acknowledgement packet size in bytes
+ const double channelCapacity = 11000000.0; // 11 Mbps (bits)
+ const double SIFS = 0.00005; // 0.05 msec, delay before ack
+ const double DIFS = 0.0001; // 0.1 msec, delay before send
+ const double SYNC = 0.00001; // 0.01 msec
+
+
+// randomly calculates negative-exponenetially-distributed-time
+double nedt(double rate)
+{
+ double u;
+ u = drand48();
+ return ((-1/rate)*std::log(1-u));
+}
+
+double dataLengthFrame(double rate)
+{
+ // http://en.cppreference.com/w/cpp/numeric/random/exponential_distribution
+ std::random_device rd;
+ std::mt19937 gen(rd());
+
+ std::exponential_distribution<> d(1); // generate nedt between 0 and 1
+
+ return int(maxPktSize * d(gen));
+}
+
+double transmissionTime(int bytes)
+{
+ return (bytes * 8) / (channelCapacity);
+}
+
+// generate a random backoff value less than or equal to T that is not currently in the backoff list
+int generateRandomBackOff(int T, const int backoff[], int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(1, T); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+
+ // make sure the backoff value is not already given to another node
+ // this is for collision avoidance as the TA told us to do, even though
+ // it doesn't really happen in real life.
+ for (int i = 0; i < N; i++)
+ {
+ if (rd == backoff[i])
+ {
+ return generateRandomBackOff(T, backoff, N);
+ }
+ }
+ return rd;
+}
+
+int randomDestination(int source, int N)
+{
+ // cited http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
+
+ std::random_device rdev;
+ std::mt19937 rgen(rdev());
+ std::uniform_int_distribution idist(0, N - 1); //(inclusive, inclusive)
+
+ int rd = idist(rgen);
+ // if random destination and source are same, recursively call the function!?
+ if (rd == source) {
+ rd = randomDestination(source, N);
+ }
+ return rd;
+}
+
+enum eventtype {
+ arrival, departure, sync, timeout
+};
+
+
+class Event {
+protected:
+ double eventTime;
+ eventtype type;
+
+
+public:
+ Event(eventtype type, double etime): eventTime(etime), type(type) {}
+ virtual ~Event(){}
+
+ double getEventTime() {
+ return eventTime;
+ }
+
+ eventtype getType()
+ {
+ return type;
+ }
+
+};
+
+class Arrival: public Event {
+ static double lambda;
+
+ int host;
+
+public:
+ Arrival(double stime, int h): Event(arrival, stime + nedt(lambda)), host(h) {}
+
+ static void setLambda(double l)
+ {
+ lambda = l;
+ }
+
+ int getHost()
+ {
+ return host;
+ }
+
+};
+
+double Arrival::lambda = 0;
+
+class Departure: public Event {
+
+ // shape of packet size distribution
+ static double mu;
+
+ bool ack; // denotes if it is an acknowedgement packet
+ int source; // source host
+ int destination; // destination host
+ int packetID; // id of packet, see host class
+ int size; // paket size in bytes, used to determine throughput
+
+public:
+ Departure(double stime, int s, int d, int id, bool a): Event(departure, stime), ack(a), source(s), destination(d), packetID(id)
+ {
+ // if ack packet, set the time to be that size
+ // time already current time, so just need to add the new time.
+ if(ack)
+ {
+ // this shouldn't be how it works in real life
+ // we're supposed to scan the channel during sifs,
+ // then if clear set channel to busy and transmit.
+ // For this project TA say just add SIFS, which is easier so OK then
+ size = ackPktSize;
+ eventTime += (SIFS + transmissionTime(size));
+ }
+ else
+ {
+ // same comment as above, except DFIS
+ size = dataLengthFrame(mu);
+ eventTime += (DIFS + transmissionTime(size));
+
+ }
+
+ }
+
+ static void setMu(double m)
+ {
+ mu = m;
+ }
+
+ bool isAck()
+ {
+ return ack;
+ }
+
+ int getSource()
+ {
+ return source;
+ }
+ int getDestination()
+ {
+ return destination;
+ }
+ int getPacketID()
+ {
+ return packetID;
+ }
+ int getSize()
+ {
+ return size;
+ }
+
+
+};
+
+double Departure::mu = 0;
+
+class Sync: public Event {
+
+ static double SYNC;
+
+public:
+ Sync(double stime): Event(sync, stime + SYNC) {}
+
+ static void setSYNC(double s)
+ {
+ SYNC = s;
+ }
+
+};
+
+double Sync::SYNC = 0;
+
+class Timeout: public Event{
+
+ static double to_time;
+
+ int host;
+ int timeoutID;
+public:
+ Timeout(double stime, int h, int id): Event(timeout, stime + to_time), host(h), timeoutID(id) {}
+
+ static void setTO(double t)
+ {
+ to_time = t;
+ }
+
+
+ int getHost()
+ {
+ return host;
+ }
+
+ int getTimeoutID()
+ {
+ return timeoutID;
+ }
+
+};
+
+double Timeout::to_time = 0;
+
+class GEL { // Global Event List
+
+ std::list GlobalEventList;
+
+public:
+ GEL() {
+ GlobalEventList = std::list(); // this line may not be necessary, but oh well
+ }
+
+ void insert(Event *event) {
+ if (GlobalEventList.size() == 0) {
+ GlobalEventList.push_front(event);
+ return;
+ }
+
+ for (std::list::iterator itr = GlobalEventList.begin(); itr != GlobalEventList.end(); itr++) {
+ if ((*itr)->getEventTime() > event->getEventTime()) {
+ GlobalEventList.insert(itr, event);
+ return;
+ }
+ }
+
+ GlobalEventList.push_back(event);
+
+
+ } // insert sorted by events time
+
+ Event* removeFirst() {
+
+ Event *firstElement = GlobalEventList.front();
+ GlobalEventList.pop_front();
+
+ return firstElement;
+ }
+};
+
+// not sure i need all this stuff yet
+class Packet {
+ int destination;
+ bool isAck; // true acknowledgement, false datapacket
+ int ackID; // used to make sure ack makes sense and stuff
+ double queueTime; // time when packet first queued, used for statistics (Network delay)
+
+
+ friend class Host;
+
+public:
+ Packet(double t, int dest, bool ack, int id = 0): destination(dest), isAck(ack), ackID(id), queueTime(t){}
+
+
+};
+
+class Host {
+ static int NumHosts; // need to know this in order to create random destination
+ static int T; // maximum backoff given no retransmissions
+ // static array so we can implement collision avoidance
+ static int* backoff; // doing it in syc tics versus real time because easier for conflict avoidance
+ // backoff < 0 means nothing in queue (nothing to transmit)
+ // backoff > 0 means waiting to transmit
+ // backoff == 0 means either transmitting or waiting for ack
+
+ int packetID; // the number of the packet sent.
+ // Not worring about overflow, and even it it does, it should still work correctly.
+ // Used to cordinate acks and timeouts.
+ // If a timeout occurs, there's a chance that there will be acks in the network
+ // that don't refer to the most recent transmission.
+
+ int droppedPackets; // not necessary for our project, but i think it might be interesting to keep track of
+ int hostID; // position in hosts array, maybe don't need this, but might if put create packets and stuff
+ int tmNum; // transmission number, max tmNum = 1 + maxRTM. Max backoff = tmNum * T
+
+ double retransmitTime; // used to calculate delay when there has been a retransmission
+ double delay; // total delay, used for statistics.
+ std::queue packetQueue; // i think its initialized implicitly
+
+public:
+ // initially set backoff to (-1) to show that nothing in queue
+ Host(int id): packetID(0), droppedPackets(0), hostID(id), tmNum(0), retransmitTime(0), delay(0){
+ backoff[id] = -1;
+ }
+
+ // initialize static variables
+ static void initHosts(int N, int t)
+ {
+ NumHosts = N;
+ backoff = new int[N];
+ T = t;
+ }
+
+ double getDelay()
+ {
+ return delay;
+ }
+
+ int getDropedPackets()
+ {
+ return droppedPackets;
+ }
+
+ void enqueueDataPacket(double stime)
+ {
+ packetQueue.push(Packet(stime, randomDestination(hostID, NumHosts), false));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet.
+ // in real life I don't think the first packet waits for a backoff,
+ // but the TAs told us to do it this way.
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+ void enqueueAckPacket(double stime, int dest, int ackID)
+ {
+
+ // In real life I don't think the ack goes in the back of the queue,
+ // But the TAs told us to do it this way.
+
+ packetQueue.push(Packet(stime, dest, true, ackID));
+ // if nothing ready to transmit, as denoted by a negative backoff value
+ // then need to set a new backoff value for this packet
+ if (backoff[hostID] < 0)
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+
+ }
+
+ // decrements backoff value if it is larger than zero
+ // returns true if this act makes the value 0, and thus the Host is ready to transmit
+ bool decrementBackoff()
+ {
+ if (backoff[hostID] > 0)
+ {
+ --(backoff[hostID]);
+ if(backoff[hostID] == 0)
+ return true;
+ }
+ return false;
+ }
+
+
+ void receiveAck(int AckID)
+ {
+ // if correct ack, can pop packet from start of queue
+ if (AckID == packetID)
+ {
+ //std::cerr << "receive correct ack, Host: " << hostID << ", AckID: " << AckID << std::endl;
+ packetQueue.pop(); // pop packet from queue
+ packetID++; // new packet to send, so increment packetID
+ tmNum = 0; // need to reset TmNum because new packet to transmit.
+ // if no more packets in queue, indicate it by setting backoff id to -1
+ if (packetQueue.empty())
+ {
+ backoff[hostID] = -1;
+ }
+ // eles if still packet to send, set new backoff value
+ else
+ {
+ backoff[hostID] = generateRandomBackOff(T, backoff, NumHosts);
+ }
+
+
+ }
+ // if AckID does not match PacketID do nothing
+ // should never get out of order ack because can only sent 1 packet at a time
+ }
+
+ void receiveTimeout(double stime, int TO_ID)
+ {
+ // if timeout refers to current packet, need to resend with larger backoff
+ if (TO_ID == packetID)
+ {
+ // if haven't reached maximum transmissions yet, need to retransmit it by resetting backoff value
+ // tmNum refers to current transmission. On transmission 3, there have been 2 retransmissions
+ // if MaxRTM = 3, then should be able to send another one.
+ // if MaxRTM = 3 and tmNum = 4, then there have already been 3 retransmissions and need to abort
+ if (tmNum <= maxRTM)
+ {
+ // need to reset packet queue time because should not double count delay when waiting for ack
+ // actually, i don't want to make it a queue of pointers so i'll do this hack instead
+ retransmitTime = stime;
+
+ // need to increase mack backoff by a multiple of (tmNum + 1),
+ // since tmNum in incremented when departure event created, but need to use that as a multiplyer here
+ backoff[hostID] = generateRandomBackOff(T * (tmNum + 1), backoff, NumHosts);
+ }
+ // else need to drop packet. Do this by pretending to ack it
+ else
+ {
+ droppedPackets++;
+ receiveAck(packetID);
+
+ }
+
+ }
+
+ }
+
+
+ // performs packet processing and prepares packet for departure
+ // returns a departure event
+ // not going to do error checking, so assumes that there is at least 1 packet in the queue and that hopeufully backoff == 0
+ // actually, maybe will do error checking
+ Departure* createDeparture(double stime)
+ {
+ // i lied, error checking
+ if (backoff[hostID] != 0)
+ std::cerr << "Host creating Departure event when backoff != 0" << std::endl;
+ // the other one should cause runtime issues if bug, so won't check for it
+ // no that's stupid
+ if (packetQueue.empty())
+ {
+ std::cerr << "Host creating Departure event when queue empty" << std::endl;
+
+ return NULL;
+ }
+
+
+
+ // get packet info
+ Packet p = packetQueue.front();
+
+ Departure* depart; // holds return value
+
+
+ //std::cerr << "creating departure with destination: " << p.destination << std::endl;
+
+ // if an ack packet, create ack event
+ // since we don't need to wait for ack, can immediatley pretend we got one
+ if (p.isAck)
+ {
+ receiveAck(packetID);
+ depart = new Departure(stime, hostID, p.destination, p.ackID, true);
+ }
+ // else need to create packet and increment tmNum
+ else
+ {
+ depart = new Departure(stime, hostID, p.destination, packetID, false);
+ tmNum ++;
+
+
+ }
+
+ // calculate delay
+ // if this is a retransmission (tmNum > 1), then need to use retransmitTime as a base
+ if (tmNum > 1)
+ {
+ delay += (depart->getEventTime() - retransmitTime);
+ }
+ // else use packet time as a base
+ else
+ {
+ delay += (depart->getEventTime() - p.queueTime);
+ }
+
+ return depart;
+
+ }
+
+ Timeout* createTimeout(double stime)
+ {
+ return new Timeout(stime, hostID, packetID);
+ }
+
+};
+
+int* Host::backoff = NULL;
+int Host::NumHosts = 0;
+int Host::T = 0;
+
+
+
+int main(int argc, char const *argv[])
+{
+
+// read from command line, but given default values
+ double lambda = 0.1; // dexcribes shape of arrival distribution
+ double mu = 1; // describes shape of distribution of PktSize (r)
+ int N = 10; // number of hosts in network.
+ int T = 400; // maximum backoff value in number sync cycles. Should be larger than N I suppose.
+ double TO = 0.005; // for project, will take values of 5, 10, or 15 msec.
+ int eventsSimulated = 100000; // the bound of for loop
+
+// these are variables used throught the program
+ double time = 0; // time simulated since start of simulation in seconds
+ double transmitted = 0; // number of bytes successfully transmitted (will include ack bytes)
+ double delay = 0; // queue + transmission delay in seconds
+ int packets = 0;
+ bool channelBusy = false; // true if channel is busy, false otherwise
+
+// containers
+ Host* *hosts; // an array of host pointers
+ GEL* eventList; // holds list of events
+
+ // check if help option set (or if only 1 argument, since that would be invalid).
+ // If so, print help information and end program
+ if ((argc > 1 && std::string("-help") == argv[1]) || argc == 2)
+ {
+ std::cout << "\nThis program simulates an IEEE 802.11-Based Wireless LAN. \n"
+ "To set parameters of network, use the following commands.\n"
+ "Default values are given in parenthesis.\n\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n"
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n"<< std::endl;
+
+ return 0;
+ }
+
+ // read in command line inputs, assume all inputs come in a -var val pair
+ for (int i = 1; i + 1 < argc; i += 2)
+ {
+ // i probably should have made this a function, but i already did the copy paste so really no use now
+ if (std::string("-N") == argv[i])
+ try{
+ N = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -N, using default value " << N << std::endl;
+ }
+ else if (std::string("-l") == argv[i])
+ try{
+ lambda = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -l, using default value " << lambda << std::endl;
+ }
+ else if (std::string("-m") == argv[i])
+ try{
+ mu = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -m, using default value " << mu << std::endl;
+ }
+ else if (std::string("-T") == argv[i])
+ try{
+ T = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -T, using default value " << T << std::endl;
+ }
+ else if (std::string("-t") == argv[i])
+ try{
+ TO = std::stod(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -t, using default value " << TO << std::endl;
+ }
+ else if (std::string("-s") == argv[i])
+ try{
+ eventsSimulated = std::stoi(argv[i+1]);
+
+ }
+ catch(std::exception e)
+ {
+ std::cerr << "invalid input for -s, using default value " << eventsSimulated << std::endl;
+ }
+ else
+ {
+ std::cout << "invalid option \"" << argv[i] <<"\". To see valid options, run \"" << argv[0] << " -help\"" << std::endl;
+ }
+ }
+
+ /*std::cout << "checking values:\n"
+ "-l: lambda(" << lambda << "), shape of arrival distribution\n"
+ "-m: mu(" << mu << "), shape of packet size distribution\n"
+ "-N: N(" << N << "), number of hosts on LAN\n"
+ "-T: T(" << T << "), maximum backoff time in sync cycles\n"
+ "-t: timeout(" << TO << "), given in msec\n" << std::endl;
+ "-s: eventsSimulated(" << eventsSimulated << "), controls length of simulation\n" << std::endl;*/
+
+
+
+
+ // Now the simulation can finally begin
+
+ hosts = new Host*[N]; // create an array to hold all Hosts
+ eventList = new GEL(); // create a list of events
+ Event* e; // holds the event currently being manipulated
+
+ // initialize static variables of events
+ Arrival::setLambda(lambda);
+ Departure::setMu(mu);
+ Sync::setSYNC(SYNC);
+ Host::initHosts(N, T);
+ Timeout::setTO(TO);
+
+
+ // initialize each host and create its initial arrival event
+ for (int i = 0; i < N; i++)
+ {
+ hosts[i] = new Host(i);
+ eventList->insert(new Arrival(time, i));
+
+ }
+
+ eventList->insert(new Sync(time)); // create the first sync event
+
+
+ for(int i = 0; i < eventsSimulated; i++)
+ {
+ // pop event to handle
+ e = eventList->removeFirst();
+
+ // update time
+ time = e->getEventTime();
+
+ if (e->getType() == arrival)
+ {
+ // cast to arrival pointer
+ Arrival *a = static_cast(e);
+
+ // check if cast actually worked
+ if (a)
+ {
+ // need to create a new arrival event for the previous arrival event's host
+ eventList->insert(new Arrival(time, a->getHost()));
+
+ // following line testing behaviour of arrival event
+ //std::cout << "process arrival event for host: " << a->getHost() << " at time: " << a->getEventTime() << std::endl;
+
+ // now need to put packet in queue of host.
+ // will generate length of packet on demand when create a departure event
+ // but need to indicate that it is not a ack packet
+ hosts[a->getHost()]->enqueueDataPacket(time);
+
+ }
+ else // not actually an arrival pointer
+ {
+ std::cerr << "error: process event of arrival type that wasn't actually an arrival event" << std::endl;
+ }
+ }
+
+
+ else if (e->getType() == departure)
+ {
+ // cast to departure pointer
+ Departure *d = static_cast(e);
+
+ // check if cast actually worked
+ if (d)
+ {
+ // keep track of bytes transmitted
+ transmitted += d->getSize();
+ packets ++;
+
+
+ // if an ack departure, need to notify receiving host
+ if (d->isAck())
+ {
+ // using an integer for packet IDs
+ hosts[d->getDestination()]->receiveAck(d->getPacketID());
+
+ }
+ // if a data departure, need to create ack packet in destination queue
+ else
+ {
+ hosts[d->getDestination()]->enqueueAckPacket(time, d->getSource(), d->getPacketID());
+ }
+ // set channel to free
+ channelBusy = false;
+
+
+ }
+ else // not actually a departure pointer
+ {
+ std::cerr << "error: process event of departure type that wasn't actually a departure event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == sync)
+ {
+ // cast to Sync pointer
+ Sync *s = static_cast(e);
+
+ // check if cast actually worked
+ if (s)
+ {
+ // need to create a new Sync event
+ eventList->insert(new Sync(time));
+
+ //std::cout << "process sync event at time: " << s->getEventTime() << std::endl;
+
+ // if channel is free, go through all hosts and decrement backoff.
+ // if backoff reaches zero, set channel to busy and create departure event
+ // also continue to decrement the rest of the backoffs to help with collision avoidance
+ if (channelBusy == false)
+ {
+ // possible host that needs to transmit
+ int hostToProcess = -1;
+ for (int i = 0; i < N; i++)
+ {
+ // decrements backoff value, returns true if backoff becomes zero
+ // need to save host index if it needs to be processed
+ // since we provide collision detection, there should only ever be one host ready to process
+ if(hosts[i]->decrementBackoff())
+ {
+ hostToProcess = i;
+ }
+
+ // if a host was selected to process, need to process it
+
+ }
+ if (hostToProcess >= 0)
+ {
+ // have the host create a departure event
+ Departure* departHelp = (hosts[hostToProcess]->createDeparture(time));
+ if (departHelp)
+ {
+ eventList->insert(departHelp);
+ // create a timeout event tied to the host, but only if not ack
+ if (!departHelp->isAck())
+ {
+ eventList->insert(hosts[hostToProcess]->createTimeout(time));
+
+ }
+ // set channel to busy
+ channelBusy = true;
+ }
+ }
+ }
+
+
+ }
+ else // not actually a sync pointer
+ {
+ std::cerr << "error: process event of sync type that wasn't actually a sync event" << std::endl;
+ }
+
+ }
+ else if (e->getType() == timeout)
+ {
+ // cast to arrival pointer
+ Timeout *t = static_cast(e);
+
+ // check if actually worked
+ if (t)
+ {
+ // tell host that timeout event occured
+ hosts[t->getHost()]->receiveTimeout(time, t->getTimeoutID());
+
+ }
+ else // not actually a timeout pointer
+ {
+ std::cerr << "error: process event of timeout type that wasn't actually a timeout event" << std::endl;
+ }
+ }
+
+ // free memory of processed event
+ delete e;
+
+
+ }
+
+
+
+ int drop = 0;
+
+ for (int i = 0; i < N; i++)
+ {
+ delay += hosts[i]->getDelay();
+ drop += hosts[i]->getDropedPackets();
+ }
+
+
+ std::cout << "Throughput: " << transmitted / time << " Bps" << std::endl;
+ std::cout << "Average Network Delay: " << delay / transmitted << " s/B" << std::endl; // I changed this to make sense
+ std::cout << "Average Network Delay: " << delay / packets << " s/packet" << std::endl; // I changed this to make sense
+ std::cout << "Average Network Delay (per instructions): " << delay / (transmitted/time) << " s^2/B" << std::endl; // This is what doesn't make sense
+
+ std::cout << "Packets Dropped: " << drop << std::endl;
+ std::cout << "Packets Sent: " << packets << std::endl;
+
+
+
+ // delete dynamically allocated data
+ for (int i = 0; i < N; i++)
+ {
+ delete hosts[i];
+ }
+ delete hosts;
+ delete eventList;
+
+
+
+}
+
+
+
+
+/*
+
+
+ Event e = Event(time + pareto(lambda), true);
+ GEL eventList = GEL();
+ eventList.insert(e);
+
+ //cerr << "hello 1" << endl;
+
+ // for 100000 events
+ // process event
+ // just going by the number given
+
+ for (int i = 0; i < eventsSimulated; i++)
+ {
+ // get closest event and update time
+ e = eventList.removeFirst();
+
+ // sums length by multiplying length by elapsed time
+ // since length = 1 could still be considered empty queue
+ // may want to chech it should be length, not length - 1
+ sumLength += max(0, length - 1) * (e.getEventTime() - time);
+ //cerr << "prev time: " << time << " event time: " << e.getEventTime() << endl;
+
+ // updates time
+ time = e.getEventTime();
+
+ // handles Arrival event
+ if (e.getIsArrival())
+ {
+ //cerr << "is Arrival, i: " << i << endl;
+ // insert new arrival event
+ eventList.insert(Event(time + pareto(lambda), true));
+
+ //cerr << "length: " << length << endl;
+
+ // if server is free, schedule a departure event, and update length
+ if (length == 0)
+ {
+ //cerr << "hello from length = 0" << endl;
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ length ++;
+ // this assumes maxbuffer is at least one,
+ // which is a good assumption because no buffer
+ // would have max buffer equal to 1
+ }
+ // else if room in buffer
+ // maxbuffer = -1 denotes infinite buffer
+ else if (maxbuffer == -1 || length - 1 < maxbuffer)
+ {
+ length ++;
+ // handles generating of service time when departure event created
+ }
+ else // no room in buffer
+ {
+ dropNum ++;
+ }
+ }
+
+ // handles departure event
+ else
+ {
+ //cerr << "is departure" << endl;
+ length --;
+
+ // if packet still in queue, create a departure event
+ if (length > 0)
+ {
+ packet = nedt(mu);
+ //cerr << "packet: " << packet << endl;
+
+ busy += packet;
+ eventList.insert(Event(time + packet, false));
+ }
+ }
+
+ }
+
+ std::cout << "lambda: ";
+ std::cout << lambda << endl;
+
+ std::cout << "mu: ";
+ std::cout << mu << endl;
+
+ std::cout << "Buffer Size: ";
+ std::cout << maxbuffer << endl;
+
+ cout << "Utilization: " << busy / time << endl;
+ cout << "Mean queue length: " << sumLength / time << endl;
+ cout << "Number of packets dropped: " << dropNum << endl << endl << endl;
+
+
+ return 0;
+}*/
+
+
+