<?xml version = "1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml">
<meta charset="UTF-8">

<head>
	<title>NDN Get File via WebSocket</title>
	
	<script type="text/javascript" src="../tools/build/ndn-js.js"></script>

	<script type="text/javascript">
		hostip = "131.179.196.232";
		//hostip = "localhost";
		//var ndncon = new NDN({port:9696,host:hostip});
		var ndncon = new NDN({port:9696,host:hostip,verify:false});
        ndncon.transport.connectWebSocket(ndncon);
        
///////////////////////////////////////////////////////////////////////////////////////////////////////////
        /*
		 * Closure for calling expressInterest to fetch big file.
		 */                                                
		var ContentClosure = function ContentClosure(ndn, T0) {
		    // Inherit from Closure.
		    Closure.call(this);
		    
		    this.T0 = T0;  // start time
		    this.ndn = ndn;
			this.totalBlocks = 0;  // total # of segments delivered to usr; 
			                       // TODO: in this test script we simply discard the content after it is received
			                       //  should consider some way to buffer the whole data in future refactor  --- SWT
		    
		    // We should always start with the first element so the first content object cannot be ooo data
		    //this.firstReceivedSegmentNumber = null;
		    //this.firstReceivedContentObject = null;
		    
		    // statistic counters
		    this.ooo_count = 0;  // out-of-order content object counter; 
		                         // when this counter reaches 3, apply fast retransmission alg.
		    this.pkt_recved = 0;  // total # of content object received
		    this.timed_out = 0;   // totle # of timed out interest
		    this.interest_sent = 1;  // there is an initial interest before calling the closure upcall
		    this.dups = 0;  // total # of dup content segments
		    
		    this.max_window = 32;  // max window size
		    this.max_retrans = 5;  // max # of trial before give up; if we fail on one segment, the entire process is aborted
		    
		    this.snd_una = 0;  // pointer to unacked segments
		    this.snd_wnd = 1;  // current window size
		    this.snd_nxt = 1;  // pointer to next interest to be sent
		    
		    this.ooo_table_size = 128;
		    this.ooo_table = [];  // hash table to mark ooo segments
		    
		    this.terminated = false;  // Set this flag after we receive all the segments; 
		};
		
		ContentClosure.prototype.upcall = function(kind, upcallInfo) {
			this.pkt_recved++;
			
		    if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
		    	if (this.terminated == false) {
			    	this.timed_out++;
			    	
			    	// Reduce window size to 1
			    	this.snd_wnd = 1;
			    	
			    	// Retransmit interest for this segment
			    	this.ndn.expressInterest(upcallInfo.interest.name, this);
					//console.log("Resend interest sent for " + upcallInfo.interest.name.getName());
					document.getElementById('content').innerHTML += "<p>Resend interest sent for " 
					                         + upcallInfo.interest.name.getName() + "</p>";
					this.interest_sent++;
					
			    	document.getElementById('content').innerHTML += "<p>Interest " + upcallInfo.interest.name.getName() + " time out.</p>";
			        document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>";
			        document.getElementById('content').innerHTML += "<p>Total number of packets: " + this.pkt_recved + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of dup segments: " + this.dups + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of interest sent: " + this.interest_sent + "</p>";
					document.getElementById('content').innerHTML += "<p>Total number of time-out interest: " + this.timed_out + "</p>";
					
					document.getElementById('content').innerHTML += "<p>SND_UNA: " + this.snd_una + "</p>";
					document.getElementById('content').innerHTML += "<p>SND_WND: " + this.snd_wnd + "</p>";
					document.getElementById('content').innerHTML += "<p>SND_NXT: " + this.snd_nxt + "</p>";
				}
		        return Closure.RESULT_OK;
		    }
		    
		    if (kind == Closure.UPCALL_CONTENT_BAD) {
		    	console.log("NdnProtocol.ContentClosure: signature verification failed");
		    	console.log(upcallInfo.contentObject.name.getName());
		    	console.log(DataUtils.toHex(upcallInfo.contentObject.signature.Witness).toLowerCase());
		    	return Closure.RESULT_OK;
		    }
		    
		    if (!(kind == Closure.UPCALL_CONTENT ||
		          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
		        // The upcall is not for us.
		        return Closure.RESULT_ERR;
		    
		    var contentObject = upcallInfo.contentObject;
		    if (contentObject.content == null) {
		        console.log("NdnProtocol.ContentClosure: contentObject.content is null");
		        return Closure.RESULT_ERR;
		    }
		
		    // Use the segmentNumber to load multiple segments.
		    var segmentNumber = DataUtils.bigEndianToUnsignedInt
		    						(contentObject.name.components[contentObject.name.components.length - 1]);
		    //console.log("Seg # " + segmentNumber + " received");
		    //console.log("Seg name " + contentObject.name.getName());
		    
		    /*
	        if (this.firstReceivedSegmentNumber == null) {
	            // This is the first call.
	            this.firstReceivedSegmentNumber = segmentNumber;
	            if (segmentNumber != 0) {
	                // Special case: Save this content object for later and request segment zero.
	                // SWT: this should not happen in normal case; 
	                //      ccnd should always return the first segment if no seg# is specified
	                this.firstReceivedContentObject = contentObject;
	                var componentsForZero = contentObject.name.components.slice
	                    (0, contentObject.name.components.length - 1);
	                componentsForZero.push([0]);
	                this.ndn.expressInterest(new Name(componentsForZero), this);
	                return Closure.RESULT_OK;
	            }
	        }
	        */
			
			// Process received data here...
			// Count content length
			//nameStr = escape(contentObject.name.getName());
			//document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
			//document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>";
		    
		    /*
		    // Check for the special case if the saved content is for the next segment that we need.
		    if (this.firstReceivedContentObject != null && 
		        this.firstReceivedSegmentNumber == segmentNumber + 1) {
		        // Substitute the saved contentObject send its content and keep going.
		        contentObject = this.firstReceivedContentObject;
		        segmentNumber = segmentNumber + 1;
		        // Clear firstReceivedContentObject to save memory.
		        this.firstReceivedContentObject = null;
		        
		        // Process received data here...
		    	// Count content length
		    	//nameStr = escape(contentObject.name.getName());
				//document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
				//document.getElementById('content').innerHTML += "<p>Content buffer length: " + contentObject.content.length + "</p>";
				this.totalBlocks++;
		    }
		    */
			
			// Record final seg# if present
			var finalSegmentNumber = null;
			if (contentObject.signedInfo != null && contentObject.signedInfo.finalBlockID != null)
				finalSegmentNumber = DataUtils.bigEndianToUnsignedInt(contentObject.signedInfo.finalBlockID);
			
			// Check for out-of-order segment
			if (segmentNumber != this.snd_una) {
				//console.log("Out-of-order segment #" + segmentNumber + " received.");
				document.getElementById('content').innerHTML += "<p>Out-of-order segment #" + segmentNumber + " received.</p>";
				this.ooo_count++;
				
				if (segmentNumber >= this.snd_nxt || segmentNumber < this.snd_una) {
					// Discard segment that is out of window
					//console.log("Out-of-window segment #" + segmentNumber);
					document.getElementById('content').innerHTML += "<p>Out-of-window segment #" + segmentNumber + "</p>";
					return Closure.RESULT_OK;
				}
				// Mark this segment in hash table
				var slot = segmentNumber % this.ooo_table_size;
				this.ooo_table[slot] = segmentNumber;
				
				if (this.ooo_count == 3) {
					// Fast retransmit
					// TODO: expressInterest for seg# = this.snd_una
					//this.snd_wnd = Math.floor(this.snd_wnd / 2) + 3;
				} else if (this.ooo_count > 3) {
					//this.snd_wnd++;
					// TODO: send a new interest if allowed by snd_wnd
					// SWT: what if we never receive the first unacked segment???
				}
				
				return Closure.RESULT_OK;
			}
			
			// In-order segment; slide window forward
			this.snd_una++
			this.totalBlocks++;
			var slot = this.snd_una % this.ooo_table_size;
			while (this.ooo_table[slot] != undefined) {
				// continue to move forward until we reach a hole in the seg# sequence
				this.ooo_table[slot] = undefined;
				this.snd_una++;
				this.totalBlocks++;
				slot = this.snd_una % this.ooo_table_size;
			}
			
			if (finalSegmentNumber != null && this.snd_una == finalSegmentNumber + 1) {
				// All blocks before final block, including final block, is received. Mission complete.
				// Record stop time and print statistic result
				this.terminated = true;
				var T1 = new Date();
				document.getElementById('content').innerHTML += "<p>Final block received.</p>";
				document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>";
				document.getElementById('content').innerHTML += "<p>Total number of blocks: " + this.totalBlocks + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of packets: " + this.pkt_recved + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of dup segments: " + this.dups + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of interest sent: " + this.interest_sent + "</p>";
				document.getElementById('content').innerHTML += "<p>Total number of time-out interest: " + this.timed_out + "</p>";
				
				document.getElementById('content').innerHTML += "<p>SND_UNA: " + this.snd_una + "</p>";
				document.getElementById('content').innerHTML += "<p>SND_WND: " + this.snd_wnd + "</p>";
				document.getElementById('content').innerHTML += "<p>SND_NXT: " + this.snd_nxt + "</p>";
				return Closure.RESULT_OK;
			}
			
			// Adjust window size
			if (this.snd_wnd < this.max_window) {
				this.snd_wnd++;
				//console.log("Window size after adjust: " + this.snd_wnd);
			}
			
			// Send the next interest if allowed by snd_wnd
			var nextNameComponents = contentObject.name.components.slice(0, contentObject.name.components.length - 1);
			//console.log("SND_UNA: " + this.snd_una);
			//console.log("SND_NXT: " + this.snd_nxt);
			while (this.snd_nxt - this.snd_una < this.snd_wnd) {
				// Make a name for the next segment and get it.
				var segmentNumberPlus1 = DataUtils.nonNegativeIntToBigEndian(this.snd_nxt);
				// Put a 0 byte in front.
				var nextSegmentNumber = new Uint8Array(segmentNumberPlus1.length + 1);
				nextSegmentNumber.set(segmentNumberPlus1, 1);
				
				nextNameComponents.push(nextSegmentNumber);
				
				var nextName = new Name(nextNameComponents);
				this.ndn.expressInterest(nextName, this);
				//console.log("Interest sent for seg # " + this.snd_nxt + " name " + nextName.getName());
				this.interest_sent++;
				
				this.snd_nxt++;
				nextNameComponents.pop();  // Remove segment number from components
			}
			
			return Closure.RESULT_OK;
		};
		
		/*
		 * Convert the big endian Uint8Array to an unsigned int.
		 * Don't check for overflow.
		 */
		function ArrayToNum(bytes) {
		    var result = 0;
		    for (var i = 0; i < bytes.length; ++i) {
		        result = result * 10;
		        result += (bytes[i] - 48);
		    }
		    return result;
		}
		
		/*
		 * Convert the int value to a new big endian Uint8Array and return.
		 * If value is 0 or negative, return Uint8Array(0). 
		 */
		function NumToArray(value) {
		    value = Math.round(value);
		    if (value <= 0)
		        return new Uint8Array(0);
		    
		    numString = value.toString();
		    var size = numString.length;
		    var result = new Uint8Array(size);
		    for (i = 0; i < size; i++) {
		    	result[i] = numString.charCodeAt(i);
		    }
		    return result;
		}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
        
        /*
        var AsyncGetClosure = function AsyncGetClosure(T0) {
        	this.T0 = T0;  // Start time
        	// Inherit from Closure.
			Closure.call(this);
		};
		
		AsyncGetClosure.prototype.upcall = function(kind, upcallInfo) {
			//console.log("Closure.upcall() executed.");
			if (kind == Closure.UPCALL_FINAL) {
				// Do nothing.
			} else if (kind == Closure.UPCALL_CONTENT) {
				var T1 = new Date();
				
				var content = upcallInfo.contentObject;
				nameStr = escape(content.name.getName());
				document.getElementById('content').innerHTML += "<p>Time elapsed: " + (T1 - this.T0) + " ms</p>"; 
				document.getElementById('content').innerHTML += "<p>Name string: " + nameStr + "</p>";
				document.getElementById('content').innerHTML += "<p>Content buffer length: " + content.content.length + "</p>";
				//console.log("In callback, nameStr: " + nameStr);
				//console.log("In callback, content: ");
				//console.log(content.content.length);
				//document.getElementById('content').innerHTML += contentObjectToHtml(content);
			} else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
				console.log("Closure.upcall called with interest time out.");
			}
			return Closure.RESULT_OK;
		};
		*/
		
		function run() {
			document.getElementById('content').innerHTML += "<p>Started...</p>";
			//ndn.expressInterest(new Name(document.getElementById('interest').value), new AsyncGetClosure( new Date() ));
			var name = new Name(document.getElementById('interest').value);
            ndncon.expressInterest( name, 
                    new ContentClosure( ndncon, new Date() ));
		}
		
	</script>
	
</head>
<body >

	<form>
		Please Enter an Interest:<br />
		<input id="interest" type="text" name="INTEREST" size="50" value="/wentao.shang/mars.jpg/%00" /> 
	</form>

	<button onclick="run()">Fetch Content</button>
	
	<p id="content">Result: <br/></p>

</body>
</html>
