| 
						
						
						
					 | 
				
				 | 
				
					@ -0,0 +1,212 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 * Simulation.cpp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 *  Created on: 16.01.2017 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 *      Author: piotrek | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "Simulation.h"
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "Node.h"
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "NATRouter.h"
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Simulation::Simulation() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						// inicjalizacja ncurses
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    initscr(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    getmaxyx(stdscr, this->rows, this->cols); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (has_colors()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    	start_color(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(0, COLOR_BLACK, COLOR_WHITE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(1, COLOR_RED, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(2, COLOR_GREEN, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(3, COLOR_YELLOW, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(4, COLOR_BLUE, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(5, COLOR_MAGENTA, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(6, COLOR_CYAN, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							init_pair(7, COLOR_WHITE, COLOR_BLACK); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->name = "Simulation"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->setLineNumber(rows -1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->setDelimiter("\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->setObjectName(&this->name); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->setColor(WHITE); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->startTime = time(NULL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //this->createThread("resizeWnd", &Simulation::resizeWndHelper, this);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this->createThread("resizeWnd", SIM_RESIZE, this); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					Simulation::~Simulation() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						//niestety nie dziala...
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    endwin(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void Simulation::createThread(string name, THREAD_TYPE type, void* context) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						struct threadParams params; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						params.type = type; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						params.context = context; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->threads.insert(pair<string, struct threadParams>(name, params)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						map<string, struct threadParams>::iterator it = threads.find(name); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (pthread_create(&it->second.thread_id, NULL, Simulation::threadWrapper, &it->second) == -1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cerr << "pthread_create() failed" << endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->threads.insert(pair<string, struct threadParams>(name, params)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						usleep(2000); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 * przy niszczeniu watku niszczy sie ncurses :( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 * TODO poszukac rozwiazania w miare mozliwosci | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void Simulation::destroyThread(string name) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						void * state; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						map<string, struct threadParams>::iterator it = threads.find(name); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (it == threads.end()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cerr << "Thread: " << name << " does not exist!" << endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (pthread_cancel(it->second.thread_id) != 0) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cerr << "pthread_cancel() failed" << endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (pthread_join(it->second.thread_id, &state) == -1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cerr << "pthread_cancel() failed" << endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if (pthread_detach(it->second.thread_id) == -1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							cerr << "pthread_detach() failed" << endl; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							exit(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						threads.erase(it); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					/*
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 * wrapper, w ktory trzeba opakowac metody do zastosowania w watku | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					*/ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void * Simulation::threadWrapper(void * context) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						struct threadParams *params = (struct threadParams*)context; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						switch(params->type) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case NODE_RECV: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								((Node *)params->context)->onRecv(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case SIM_TIMER: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							    ((Simulation *)params->context)->timer(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							    break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							case SIM_RESIZE: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							    ((Simulation *)params->context)->resizeWnd(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							    break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void Simulation::resizeWnd() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(true) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							getmaxyx(stdscr, this->rows, this->cols); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//refresh();
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void Simulation::timer() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						char str[10]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						int h,m, s; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						unsigned long timeElapsed; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						while(true) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							refresh(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							timeElapsed = time(NULL) - this->startTime; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							h =  timeElapsed / 3600; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							m = (timeElapsed % 3600) / 60; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							s = (timeElapsed % 3600) % 60; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//refresh();
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sprintf(str, "%02d:%02d:%02d", h, m, s); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							move(0, this->cols-strlen(str)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							printw(str); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							usleep(100000); // 100 ms
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//sleep(1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void Simulation::p2pSimulation() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Creating P2P peers"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Node peer1("Peer 1", "192.168.1.2", "255.255.255.0", "192.168.1.1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer1.setLogParams(0, GREEN, "\t\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Node peer2("Peer 1", "10.0.0.2", "255.255.255.0", "10.0.0.1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer2.setLogParams(1, CYAN, "\t\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer1.print("IP 192.168.1.2/24, Gateway: 192.168.1.1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer2.print("IP 10.0.0.2/24, Gateway: 10.0.0.1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Creating NAT devices"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						NATRouter r1("Router 1", "192.168.1.1", "255.255.255.0"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						NATRouter r2("Router 2", "10.0.0.1", "255.255.255.0"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.setLogParams(2, RED, "\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r2.setLogParams(4, MAGENTA, "\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.print("IP 192.168.1.1/24"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r2.print("IP 10.0.0.1/24"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Setting WAN configuration"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.setWanIp("41.42.43.44"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.setWanMask("255.255.255.255"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r2.setWanIp("45.46.47.48"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r2.setWanMask("255.255.255.255"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.print("WAN IP 41.42.43.44/32"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r2.print("WAN IP 45.46.47.48/32"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Creating P2P server"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						Node server("Server", "80.80.90.91", "255.255.255.255"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						server.setLogParams(3, YELLOW, "\t\t"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						server.print("IP 80.80.90.91/32"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Plugging Peer1 <---> Router 1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer1.connectNode(&r1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Plugging Peer2 <---> Router 2"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						peer2.connectNode(&r2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Plugging Router 1 <---> Router 2"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						r1.connectNode(&r2, true); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Plugging Server <---> Router 1"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						server.connectNode(&r1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Plugging Server <---> Router 2"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						server.connectNode(&r2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sleep(3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->print("Starting simulation..."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->createThread("r1", NODE_RECV, &r1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						this->createThread("r2", NODE_RECV, &r2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} |