From 9e4550706bd263970971de01332e2511a64f37da Mon Sep 17 00:00:00 2001
From: rupumped <nselby3@gatech.edu>
Date: Thu, 30 Nov 2017 00:42:38 -0500
Subject: [PATCH] Heartbeat and disconnect

---
 README.md      |  4 +--
 sim/manager.js | 66 ++++++++++++++++++++++++++++++++++++--------------
 sim/sim.js     | 45 +++++++++++++++++++++++++---------
 3 files changed, 83 insertions(+), 32 deletions(-)

diff --git a/README.md b/README.md
index fe5ab2d..330358f 100644
--- a/README.md
+++ b/README.md
@@ -171,7 +171,7 @@ elseif packet is standard flood:
 			if LUT has destination address:
 				send packet to port which minimizes C(hops, buffer) = hops + \lambda*buffer as standard packet
 			else:
-				send packet to all ports
+				send packet to all ports except one from which it was received
 
 elseif packet is ack flood
     remove packet src. from LUT at that port if it exists
@@ -182,7 +182,7 @@ elseif packet is ack flood
         if LUT has destination address:
             send packet to port which minimizes C(hops, buffer) = hops + \lambda*buffer as standard ACK
         else:
-            send packet to all ports
+            send packet to all ports except one from which it was received
 
 else:
     write buffer depth to LUT
diff --git a/sim/manager.js b/sim/manager.js
index ac6d2e1..e13093e 100644
--- a/sim/manager.js
+++ b/sim/manager.js
@@ -1,10 +1,10 @@
 function Manager(self) {
     self.manager = this;
 
-    const STD = 252;
-    const ACK = 253;
-    const STF = 254;
-    const ACF = 255;
+    const STD = 252;                    // Standard Message label
+    const ACK = 253;                    // Acknowledgement label
+    const STF = 254;                    // Standard Flood label
+    const ACF = 255;                    // Flood ACK label
 	
     this.ports = [];
     this.numports = 0;
@@ -19,7 +19,8 @@ function Manager(self) {
         for (var p = 0; p < numports; p++) {
             this.addr_table[p] = {
                 dests: {},
-                buff: 0
+                buff: 0,
+                heartbeat: false
             };
         }
     };
@@ -79,9 +80,34 @@ function Manager(self) {
 //        self.log(this.buffer);
         if (this.buffer.length > 0) {
             this.handlePacket(this.buffer.shift());
+        } else {
+            self.setColor("black");
         }
 //        self.log(`checked buffer of node ${self.id}`);
     };
+    
+    this.heartbeat = function() {
+        for (let p=0; p<this.numports; p++) {
+            this.sendPacket(this.buffer.length, undefined, undefined, undefined, undefined, undefined, p);
+        }
+    };
+    
+    this.takePulse = function() {
+        for (let p=0; p<this.numports; p++) {
+            if (this.addr_table[p].heartbeat) {
+                this.addr_table[p].heartbeat = false;
+            } else {
+                for (var prop in this.addr_table[p].dests) {
+                    if (this.addr_table[p].dests.hasOwnProperty(prop)) {
+                        this.addr_table[p].dests = {};
+                        this.addr_table[p].buff = 0;
+                        self.log(`did not receive heartbeat from port ${p}`);
+                        return;
+                    }
+                }
+            }
+        }
+    };
 
     this.sendPacket = function(start, dest=-1, hopcount=0, src=self.id, size=0, data=null, port=-1) {
         var packet = {
@@ -112,7 +138,10 @@ function Manager(self) {
         var packet = o.obj;
         packet.port = port;
         
-        if (this.buffer.length < this.maxBufferSize) {
+        if (packet.start !== STD && packet.start !== ACK && packet.start !== STF && packet.start !== ACF) {
+            this.addr_table[port].buff = packet.start;
+            this.addr_table[port].heartbeat = true;
+        } else if (this.buffer.length < this.maxBufferSize) {
             this.buffer.push(packet);
 	}
     };
@@ -127,26 +156,26 @@ function Manager(self) {
         }
         
         if (packet.start === STD) {				// Standard Packet
+            self.setColor("blue");
             if (packet.dest === self.id) {                                      // If I am destination
                 const nextPort = this.getMinCostPort(packet.src);               // Pick the port to send ACK based off minimizing cost
                 self.log(`got message ${packet.data}. ACKing port ${nextPort}`);
-                this.sendPacket(ACK, packet.src, 0, self.id, nextPort);
+                this.sendPacket(ACK, packet.src, undefined, self.id, undefined, undefined, nextPort);
             } else {
                 packet.hopcount++;                                              // Increment hopcount
                 const nextPort = this.getMinCostPort(packet.dest);              // Pick the port to send to based off minimizing cost
                 if (nextPort === -1) {                                          // If LUT does not have dest
                     self.log(`flooding message ${packet.data}`);
                     for (let p = 0; p < this.numports; p++) {                   // Flood packet
-                        if (p !== packet.port) {
-                            this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p);
-                        }
+                        this.sendPacket(STF, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, p);
                     }
                 } else {                                                        // If LUT does have dest, send to that port
-                    self.log(`sending packet ${packet.data}`);
+                    self.log(`sending packet ${packet.data} along port ${nextPort}`);
                     this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort);
                 }
             }
         } else if (packet.start === ACK) {			// Acknowledgement
+            self.setColor("red");
             if (packet.dest === self.id) {                                      // If I am destination
                 self.log(`got ACK from ${packet.src}`);
             } else {
@@ -155,15 +184,15 @@ function Manager(self) {
                 if (nextPort === -1) {                                          // If LUT does not have dest
                     self.log(`flooding ACK`);
                     for (let p = 0; p < this.numports; p++) {                   // Flood ACK
-                        if (p !== packet.port)
-                            this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p);
+                        this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p);
                     }
                 } else {                                                        // If LUT does have dest, send to that port
-                    self.log(`forwarding ACK`);
+                    self.log(`forwarding ACK along port ${nextPort}`);
                     this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort);
                 }
             }
         } else if (packet.start === STF) {			// Standard Flood
+            self.setColor("cyan");
             if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it
                 delete this.addr_table[packet.port].dests[packet.dest];         // ...if that node had known, it wouldn't have forwarded it as a flood.
             const thisFlood = {                                                 // Static information within packet for comparison
@@ -192,11 +221,12 @@ function Manager(self) {
                         }
                     }
                 } else {                                                        // If LUT does have dest, send to that port
-                    self.log(`forwarding message ${packet.data}`);
+                    self.log(`forwarding message ${packet.data} along ${nextPort}`);
                     this.sendPacket(STD, packet.dest, packet.hopcount, packet.src, packet.size, packet.data, nextPort);
                 }
             }
         } else if (packet.start === ACF) {			// ACK Flood
+            self.setColor("magenta");
             if (this.addr_table[packet.port].dests.hasOwnProperty(packet.dest)) // If I thought this port could send to destination, remove it
                 delete this.addr_table[packet.port].dests[packet.dest];         // ...if that node had known, it wouldn't have forwarded it as a flood.
             if (packet.dest === self.id) {                                      // If I am destination
@@ -220,12 +250,12 @@ function Manager(self) {
                             this.sendPacket(ACF, packet.dest, packet.hopcount, packet.src, 0, null, p);
                     }
                 } else {                                                        // If LUT does have dest, send to that port
-                    self.log(`forwarding ACK`);
+                    self.log(`forwarding ACK along port ${nextPort}`);
                     this.sendPacket(ACK, packet.dest, packet.hopcount, packet.src, 0, null, nextPort);
                 }
             }
-        } else {                                                // Buffer Update
-            this.addr_table[packet.port].buff = packet.start;
+        } else {                                                // Buffer Update. Should have been handled elsewhere
+            self.log(`Packet start error`);
         }
     };
 
diff --git a/sim/sim.js b/sim/sim.js
index 50c7c76..88dd984 100755
--- a/sim/sim.js
+++ b/sim/sim.js
@@ -4,14 +4,16 @@ var net = require("./network"),
 const startupDelay = 100;
 const connectDelay = 100;
 const bufferCheckDelay = 1000;
+const heartbeatPeriod = 400;
 
 // INITIALIZE NETWORK TOPOLOGY HERE
 var initTopology = [
-	[1,2],
-	[0,3],
-        [0,4],
-        [1,4],
-        [3,2]
+	[1,2],      // 0
+	[0,3],      // 1
+        [0,4,5],    // 2
+        [1,4],      // 3
+        [3,2],      // 4
+        [2]         // 5
 ];
 
 // Don't touch this code
@@ -34,6 +36,12 @@ for (let i = 0; i < initTopology.length; i++) {
 		this.tick(bufferCheckDelay, function() {
 			this.manager.checkBuffer();
 		});
+		this.tick(heartbeatPeriod, function() {
+			this.manager.heartbeat();
+		});
+                this.tick(2*heartbeatPeriod, function() {
+                        this.manager.takePulse();
+                });
 	});
 	for (let j = 0; j < initTopology[i].length; j++) {
 		if (initTopology[i][j] == -1) {
@@ -48,17 +56,30 @@ for (let i = 0; i < initTopology.length; i++) {
 	}
 }
 
+//----------------------------------------------------------------------------//
 // PUT CUSTOM CODE HERE:
-
-//send(0, 1, 'hi!', 1000);
-//send(3, 3, 'what is up?', 1500);
-//disconnect(0, 1, 2, 2, 1700);
-//send(2, 2, 'You cannot see this cause we are not connected', 2000);
-//send(2, 0, 'we are friends now', 2500);
 sendPacket(0,4,1,"Hello Four!",1000);
-sendPacket(0,4,1,"I love you, Four!",6000)
+
+// To test link failure, uncomment one. To test node failure, uncomment both.
+//disconnect(0,1,2,0,6000);
+//disconnect(2,1,4,1,6000);
+
+// To test how network reacts to heavy traffic at a desired node, uncomment.
+//sendPacket(5,2,1,"Distraction 0!",6000);
+//sendPacket(5,2,1,"Distraction 1!",6000);
+//sendPacket(5,2,1,"Distraction 2!",6000);
+//sendPacket(5,2,1,"Distraction 3!",6000);
+//sendPacket(5,2,1,"Distraction 4!",6000);
+//sendPacket(5,2,1,"Distraction 5!",6000);
+//sendPacket(5,2,1,"Distraction 6!",6000);
+//sendPacket(5,2,1,"Distraction 7!",6000);
+//sendPacket(5,2,1,"Distraction 8!",6000);
+
+sendPacket(4,0,1,"I love you, One!",8000);
+
 
 //Don't add stuff below this:
+//----------------------------------------------------------------------------//
 
 for (let i = 0; i < initTopology.length; i++) {
 	net.add(1, clients[i]);
-- 
GitLab