diff -ur ns-2.32-orig/queue/drop-tail.cc ns-2.32/queue/drop-tail.cc --- ns-2.32-orig/queue/drop-tail.cc 2004-10-29 01:35:37.000000000 +0200 +++ ns-2.32/queue/drop-tail.cc 2008-03-21 18:54:22.000000000 +0100 @@ -87,7 +87,7 @@ if (summarystats) { Queue::updateStats(qib_?q_->byteLength():q_->length()); } - + backlog_=byteLength();//DAMA UTOR. Export queue lenght in bytes. int qlimBytes = qlim_ * mean_pktsize_; if ((!qib_ && (q_->length() + 1) >= qlim_) || (qib_ && (q_->byteLength() + hdr_cmn::access(p)->size()) >= qlimBytes)){ diff -ur ns-2.32-orig/queue/drop-tail.h ns-2.32/queue/drop-tail.h --- ns-2.32-orig/queue/drop-tail.h 2004-10-29 01:35:37.000000000 +0200 +++ ns-2.32/queue/drop-tail.h 2008-03-21 18:59:08.000000000 +0100 @@ -54,10 +54,12 @@ bind_bool("queue_in_bytes_", &qib_); // boolean: q in bytes? bind("mean_pktsize_", &mean_pktsize_); // _RENAMED("drop-front_", "drop_front_"); + bind("backlog_", &backlog_); } ~DropTail() { delete q_; } + int backlog_; //DAMA UTOR. variable to export queue lenght in bytes protected: void reset(); int command(int argc, const char*const* argv); diff -ur ns-2.32-orig/satellite/satlink.cc ns-2.32/satellite/satlink.cc --- ns-2.32-orig/satellite/satlink.cc 2005-09-21 23:45:04.000000000 +0200 +++ ns-2.32/satellite/satlink.cc 2008-03-21 19:17:25.000000000 +0100 @@ -728,4 +728,537 @@ return -1; } +//Start modifications +/*==========================================================================*/ +/* DAMA UTOR. Implementation + */ +////////////////////////////////////////////////////// +//RCST Class + +//TCL binding +static class DamaTerminalProfileClass : public TclClass { +public: + DamaTerminalProfileClass() : TclClass("DamaTerminalProfile") {} + TclObject* create(int, const char*const*) { + return (new DamaTerminalProfile()); + } +} class_dama_terminal_profile; + +//Debug routine +void DamaTerminalProfile::show_buffer() +{ + +printf("[debug]Terminal_id_ %i assignment buffer: ",terminal_id_); + +for (int i=0 ; i< dama_L_ ; i++) +{ + printf ("%i ",buffer[i]); + +} +int a=requestPtr; +int b=(requestPtr+1) % dama_L_; + +printf("(write pointer: %i read pointer %i)\n",a,b); + +printf("[debug]Terminal_id_ %i vbdc buffer: ",terminal_id_); + +for (int i=0 ; i< dama_L_ ; i++) +{ + //printf ("%i ",buffer[i]); + printf ("%i ",vbdc_storage[i]); +} + +a=vbdcPtr; +printf("(pointer: %i)\n",a); +} + +void DamaTerminalProfile::push(int new_value) +{ +int actual_slot_value; +int writePtr = requestPtr; +requestPtr = (requestPtr + 1 ) % dama_L_; +int readPtr = requestPtr; + +//When NCC pushes new_value as new slot assignment value +//Store it and widthrow the dama_L_(th) previous one + +buffer[writePtr] = new_value; +actual_slot_value = buffer[readPtr]; + +//Force current output rate according to correct rate (cra_ slots are always granted) +((DamaMac*)mac_)->slot_= (actual_slot_value + cra_); +} + +int DamaTerminalProfile::compute_request() +{ +int slot_needed=0; +int return_value=0; +int total_vbdc_request=0; +int bytes_for_request=0; +int bytes_in_queue=((DropTail*)q_)->backlog_; +int bytes_left; +int bps = ((DamaMac*)mac_)->bytes_per_superframe_; + + +//perform RBDC request: +if (rbdc_){ + bytes_for_request = (int)( (1-gamma_) * rbdc_old_request + gamma_ * bytes_in_queue); + rbdc_old_request = bytes_for_request; + bytes_for_request = (bytes_for_request < rbdc_*bps) ? bytes_for_request : rbdc_*bps; //limit slot needed to rbdc_ + + slot_needed = (int)(bytes_for_request + bps -1)/bps ; + + if (slot_needed==0 && bytes_in_queue!=0) slot_needed = 1; //get at least 1 slot on queue not empty + + return_value+=slot_needed; //Update return value +} + +bytes_left = bytes_in_queue - bytes_for_request;//- (slot_needed * bps); +if (bytes_left<0) bytes_left=0; //This should happen no more + +slot_needed=0; + +//Perform VBDC request: +//ONLY go for VBDC if we have it *AND* +//RBDC is already requesting all its capacity...Bugfix! +if (vbdc_ && (return_value==rbdc_)){ + //vbdc_storage[vbdcPtr] = 0;//set to 0 the L-th previous request before sum + for (int j=0;jtotal_vbdc_request) + { + slot_needed-=total_vbdc_request; + slot_needed = (slot_needed < vbdc_) ? slot_needed : vbdc_; + vbdc_storage[vbdcPtr] = slot_needed; + } + else + { + vbdc_storage[vbdcPtr] = 0; + slot_needed=0; + } + vbdcPtr = (vbdcPtr+1) % dama_L_; + return_value += slot_needed; +} + +return return_value; //return a single request with all slots needed regardless of the source (rbdc/vbdc) +} + +int DamaTerminalProfile::command(int argc, const char*const* argv) +{ + if (argc == 3) { + if (strcmp(argv[1], "init_buffer") == 0) { + dama_L_ = atoi(argv[2]); + buffer = new int[dama_L_]; + vbdc_storage = new int[dama_L_]; + for (int i=0 ; i < dama_L_ ; i++) + buffer[i] = vbdc_storage[i] = 0; + requestPtr = 0; + vbdcPtr=0; + return TCL_OK; + } else if (strcmp(argv[1], "show_buffer") == 0) { + show_buffer(); + return TCL_OK; + } + else if (strcmp(argv[1], "set_mac") == 0) { + mac_ = (Mac *)TclObject::lookup(argv[2]); + if (!mac_) + return TCL_ERROR; + return TCL_OK; + } + else if (strcmp(argv[1], "set_q") == 0) { + q_ = (Queue *)TclObject::lookup(argv[2]); + if (!q_) + return TCL_ERROR; + return TCL_OK; + } else if (strcmp(argv[1], "force_slot") == 0) { + ((DamaMac*)mac_)->slot_= atoi(argv[2]); + return TCL_OK; + }else if (strcmp(argv[1], "force_cra") == 0) { + cra_= atoi(argv[2]); + return TCL_OK; + }else if (strcmp(argv[1], "force_rbdc") == 0) { + rbdc_= atoi(argv[2]); + return TCL_OK; + }else if (strcmp(argv[1], "force_vbdc") == 0) { + vbdc_= atoi(argv[2]); + return TCL_OK; + } + + + } + + return TCL_ERROR; +} + +DamaTerminalProfile::DamaTerminalProfile():cra_(1),rbdc_(0),vbdc_(0),gamma_(0.9), + rbdc_old_request(0),Ki_(1),prio_(1)//initiate request profile with default values +{ + bind("cra_",&cra_); + bind("rbdc_",&rbdc_); + bind("vbdc_",&vbdc_); + bind("dama_L_",&dama_L_); + bind("rbdc_gamma_",&gamma_); + bind("terminal_id_",&terminal_id_); + bind("Ki_",&Ki_); + bind("prio_",&prio_); + + } + +////////////////////////////////////////////////////// +//DAMA MAC Class + +//TCL binding +static class DamaMacClass : public TclClass { +public: + DamaMacClass() : TclClass("Mac/Sat/Dama") {} + TclObject* create(int, const char*const*) { + return (new DamaMac()); + } +} sat_class_damamac; + +//Constructor +DamaMac::DamaMac() : SatMac() , send_timer_(this), recv_timer_(this), superframe_timer_(this),sfid(0) +{ + bind("frame_per_superframe_", &frame_per_superframe_); + bind("slot_per_frame_", &slot_per_frame_); + bind("bytes_per_superframe_",&bytes_per_superframe_); + bind("superframe_duration_",&superframe_duration_); + bind("dama_L_",&dama_L_); + bind("slot_", &slot_); + +} + + +void +DamaTimer::expire (Event * /* e */ ) +{ + a_->dama(); +} + +double DamaMac::incr_delay = 0; + +void DamaMac::sendUp(Packet* p) +{ + hdr_mac* mh = HDR_MAC(p); + int dst = this->hdr_dst((char*)mh); // mac destination address + double txd = 0; + if (((u_int32_t)dst != MAC_BROADCAST) && (dst != index_)) { + drop(p); + return; + } + // First bit of packet has arrived-- wait for + // (txtime + delay_) before sending up + //Scheduler::instance().schedule(uptarget_, p, delay_ + mh->txtime()); + txd = delay_ + mh->txtime(); + Scheduler::instance().schedule(uptarget_, p, txd); + +} + +void DamaMac::sendDown(Packet* p) +{ + Scheduler& s = Scheduler::instance(); + double txt,rt; + // LINK_HDRSIZE is defined in satlink.h. This is the size of header + // information for all layers below IP. Alternatively, one could + // derive this information dynamically from packet headers. + int packetsize_ = HDR_CMN(p)->size() + LINK_HDRSIZE; + assert (bandwidth_ != 0); + + txt = txtime(packetsize_); + + if (slot_ == 0) + { + printf ("[warning] Time %f: slot is 0!\n", Scheduler::instance().clock()); + //s.schedule(&hSend_, p , 0.1); + slot_=1; + //HDR_MAC(p)->txtime() = 1; + } + + // For convenience, we encode the transmit time in the Mac header + // The packet will be held (for collision detection) for txtime + // at the receiving mac. + + // Callback for when this packet's transmission will be done + + //DAMA varaible capacity according to NCC response (float BugFix!): + rt = txt * ((float(slot_per_frame_) / slot_)) ;//adjust output according do BoD result + HDR_MAC(p)->txtime() = rt; + downtarget_->recv(p, this); + s.schedule(&hRes_, &intr_, rt); //go down at rt instead than txt +} + + +//Init static variables - MAXTERMINAL Max num of terminals- +int DamaMac::last_terminal = 0; +int DamaMac::tot_cra_slots_ = 0; +DamaTerminalProfile** DamaMac::rcst_ = new DamaTerminalProfile* [MAXTERMINAL];//array for terminal references +///////////////// + +void DamaMac::init(int cra){ +//Update total of CRA slots to remove from available slots. +//Other operations to perform on a new terminal joining the pool must be put here. + tot_cra_slots_+=cra; //TODO: re-check here!!!CRA is in timeslots?? + printf("Added %i CRA slots. Total now is %i CRA slots out of %i\n", cra,tot_cra_slots_,slot_per_frame_ ); + if (tot_cra_slots_>slot_per_frame_){ + printf ("Too many CRA requests. I quit!\n"); + exit(-1); + } +} + +void DamaMac::run(const char* type){ +//Initialize the dama scheduler. +request_vector = new int [MAXTERMINAL]; +response_vector = new int [MAXTERMINAL]; +for (int i=0 ; i < MAXTERMINAL ; i++) + request_vector[i] = response_vector[i] = 0; + +if (strcmp(type, "default") == 0) + { + //Default DAMA scheduler is 1 (serv first terminals first) + DamaScheduler=1; + } +else if (strcmp(type, "rr") == 0) + { + //Round Robin - Assign a slot per terminal in RR until available + DamaScheduler=2; + } +else if (strcmp(type, "proportional") == 0) + { + //Proportional allocation - all requests weithed + DamaScheduler=3; + } +else if (strcmp(type, "prio") == 0) + { + //Priority allocation - Experimental + DamaScheduler=4; + } +else + { + //Unknown. Using default. + DamaScheduler=1; + printf ("[Warning] Unknown DAMA scheduler \"%s\", running default one\n", type); + } + +superframe_timer_.resched (superframe_duration_); + +} + +void DamaMac::dama(){ +/* The variable DamaScheduler indicates the +choice of different allocation strategies! */ + +int cont=0; +int total_requests=0; +double ratio=1.0; + +sfid++; //increment superframe identifier +assigned_slots_=0; + +//**************** +//Part 1) COLLECT ALL REQUESTS +/////////////////////// +for (cont=0 ; cont < last_terminal ; cont++){ + //Poll each terminal to get slot requests + request_vector[cont] = DamaMac::rcst_[cont]-> compute_request(); + total_requests+=request_vector[cont]; +} +//**************** + +//**************** +//Part 2) DAMA ALGORITHM +/////////////////////// + +switch (DamaScheduler) { +case 1: +/*simple dama algorithm: assign slots as they + are requested until we have them. First terminals + have higher priority, last ones could starve.*/ + + for (cont=0 ; cont= (slot_per_frame_ - tot_cra_slots_ - assigned_slots_)){ + response_vector[cont] = (slot_per_frame_ - tot_cra_slots_ - assigned_slots_); + } else{ + response_vector[cont] = request_vector[cont]; + } + assigned_slots_+=response_vector[cont]; + } +break; + +/////////////////////// +case 2: +/*round robin algorithm: assign slots one by one + in order among all terminals until available.*/ + +total_requests = MIN (total_requests, (slot_per_frame_ - tot_cra_slots_)); + +cont=0; + +while (assigned_slots_ < total_requests){ + if (request_vector[cont]>response_vector[cont]) + { + response_vector[cont]++; + assigned_slots_++; + } + cont = (cont+1) % last_terminal; + } + +break; +/////////////////////// +case 3: +/*proportional dama algorithm: assign slots maintaining + request ratio*/ +if (total_requests>0) + { + ratio = MIN ((double)(slot_per_frame_ - tot_cra_slots_)/(double)total_requests, 1); + //in case total slots requested is less the the overall capacity we don't need to apply the ratio + for (cont=0 ; cont= + (slot_per_frame_ - tot_cra_slots_ - assigned_slots_)){ + response_vector[cont] = (slot_per_frame_ - tot_cra_slots_ - assigned_slots_); + } else{ + response_vector[cont] = (int)floor(ratio*request_vector[cont]); + } + assigned_slots_+=response_vector[cont]; + } +} + +break; +/////////////////////// +case 4: +//Prio scheduler - SLA/Coding based scheduler + +double tot_priority = 0; +int total_requests_ts = 0; +int total_requests_atm=0; + +//startup +for (cont=0; contprio_ ; + total_requests_ts += (int)ceil((double) request_vector[cont]/DamaMac::rcst_[cont]->Ki_); //here there is cross layer info too! + total_requests_atm += request_vector[cont];//For statistics only +} + +double mu_high = tot_priority/ (double) (slot_per_frame_ - tot_cra_slots_); +double mu_low = 0; +double mu_target = mu_high/2; +int actual_sum_ts = 0; +int actual_sum_atm = 0; //For statistics only!! +int timeout = 0; + +if ( total_requests_ts > (slot_per_frame_ - tot_cra_slots_)) { + +while (actual_sum_ts != (slot_per_frame_ - tot_cra_slots_)) +{ +timeout++; +actual_sum_ts=0; +actual_sum_atm=0; + +for (cont = 0 ; cont < last_terminal ; cont++){ + response_vector[cont] = MIN ((int)floor((double)DamaMac::rcst_[cont]->prio_/ mu_target), request_vector[cont]); + response_vector[cont] = MIN (response_vector[cont],(slot_per_frame_ - tot_cra_slots_)); + actual_sum_ts+=(int)ceil((double)response_vector[cont]/DamaMac::rcst_[cont]->Ki_); + actual_sum_atm += response_vector[cont]; +} + +if (actual_sum_ts < (slot_per_frame_ - tot_cra_slots_)) + { + mu_high=mu_target; + } else { + mu_low=mu_target; + } + mu_target= (mu_high+mu_low) /2; + +//emergency exit in case solution is not found due to integer crounding of solution + if (timeout > 100){ + if (actual_sum_ts > (slot_per_frame_ -tot_cra_slots_)) + printf ("**Warning!** too much timeslots have been assigned after timeout (+%i).\nBackup to last valid solution!\n" + , actual_sum_ts - (slot_per_frame_- tot_cra_slots_) ); + actual_sum_ts=0; + actual_sum_atm=0; + for (cont = 0 ; cont < last_terminal ; cont++){ + //mu_high is the latest mu for which the actual_sum_ts is lesser than resources! + response_vector[cont] = MIN ((int)floor((double)DamaMac::rcst_[cont]->prio_ / mu_high), request_vector[cont]); + response_vector[cont] = MIN (response_vector[cont],(slot_per_frame_ - tot_cra_slots_)); + actual_sum_ts+=(int)ceil((double)response_vector[cont]/DamaMac::rcst_[cont]->Ki_); + actual_sum_atm += response_vector[cont]; + } + break; + } + +} + + +} else { +//lower requests than available resources (at TS level). +//Satisfy all: +//Direct assignment! +for (cont=0;cont < last_terminal ; cont++){ + response_vector[cont] = request_vector[cont]; + actual_sum_ts = total_requests_ts; + actual_sum_atm += response_vector[cont]; + } +} +/////////////// exit case 4 //////////// +break; + +} + + +//**************** + +//**************** +//Part 3) +//Give terminals new allocation response . +//Terminals maintain a circular buffer to use the L-th previous DAMA decision +//so that elaboration and propagation delay is taken into account. + +for (cont = 0 ; cont < last_terminal ; cont++){ + + DamaMac::rcst_[cont]->push(response_vector[cont]); + response_vector[cont]=0; + } + +//reschedule the DAMA scheduler: +superframe_timer_.resched (superframe_duration_); +} + +//TCL commands handler +int DamaMac::command(int argc, const char*const* argv) +{ +if (argc == 3) { + if (strcmp(argv[1], "add_to_list") == 0) { + //put the reference of DamaTerminalProfile into a static array. + if (last_terminal == MAXTERMINAL) //max number of terminals overcame! Return error. + return TCL_ERROR; + DamaMac::rcst_[last_terminal] = (DamaTerminalProfile*) TclObject::lookup(argv[2]); + if (DamaMac::rcst_[last_terminal] == 0) + return TCL_ERROR; + last_terminal++; + return TCL_OK; + } //TODO add command "remove_from_list" to handle terminals LOGOFF + else if (strcmp(argv[1], "run_dama_scheduler") == 0) { + run((char*)argv[2]); + return TCL_OK; + } + else if (strcmp(argv[1], "refresh") == 0) { + init(atoi(argv[2])); + return TCL_OK; + } + } +else if (argc == 2) { + if (strcmp(argv[1], "run_dama_scheduler") == 0) { + run("default"); + return TCL_OK; + } + } + +return SatMac::command(argc, argv); +} + +//End changes! +/////////////////////////////// diff -ur ns-2.32-orig/satellite/satlink.h ns-2.32/satellite/satlink.h --- ns-2.32-orig/satellite/satlink.h 2005-09-21 22:52:47.000000000 +0200 +++ ns-2.32/satellite/satlink.h 2008-03-21 19:07:47.000000000 +0100 @@ -58,6 +58,11 @@ #define LINK_ISL_INTERPLANE 7 #define LINK_ISL_CROSSSEAM 8 +#define MAXTERMINAL 100 + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + + class SatLinkHead; class SatTrace; class SatNode; @@ -221,4 +226,82 @@ }; +/////////////////////////////////////////////////////////////////////////////// +//DAMA UTOR. Start modifications +//Class to maintain terminal status and profile +class DamaTerminalProfile : public TclObject { +public: + DamaTerminalProfile(); + int command(int argc, const char*const* argv); + Queue* q_; + Mac* mac_; + void push(int new_value); + int* buffer; + int dama_L_; + int requestPtr; + int* vbdc_storage;//store values of previous requests + int vbdcPtr; + int bytes_to_send; + void show_buffer(); + int compute_request(); + int terminal_id_; +//protected: + int cra_; + int rbdc_; + int vbdc_; + double gamma_; + int rbdc_old_request; + int Ki_; //Adaptive coding gain + double prio_; // priority cross-layer +}; + +class DamaMac; + +class DamaTimer:public TimerHandler +{ +public: + DamaTimer (DamaMac * a):TimerHandler () + { + a_ = a; + } +protected: + virtual void expire (Event * e); + DamaMac *a_; +}; + + +class DamaMac : public SatMac { +public: + DamaMac(); + void sendDown(Packet* p); + void sendUp(Packet *p); + void init(int cra); //To call on new terminal added to the pool. + int command(int argc, const char*const* argv); + //static array and pointer to maintain the list of terminals + static DamaTerminalProfile** rcst_; //store terminal config + static int last_terminal; + static int tot_cra_slots_; + int bytes_per_superframe_; + static double incr_delay; + int slot_per_frame_ ; + int slot_; + void dama(); +protected: + MacSendTimer send_timer_; + MacRecvTimer recv_timer_; + int frame_per_superframe_; + double superframe_duration_; + int assigned_slots_; + void run(const char* type); + int max_terminals_; + int dama_L_; + int* request_vector; + int* response_vector; + int DamaScheduler; + DamaTimer superframe_timer_; + int sfid; +}; + + + #endif diff -ur ns-2.32-orig/tcl/lib/ns-sat.tcl ns-2.32/tcl/lib/ns-sat.tcl --- ns-2.32-orig/tcl/lib/ns-sat.tcl 2002-07-10 04:29:50.000000000 +0200 +++ ns-2.32/tcl/lib/ns-sat.tcl 2008-03-21 19:14:03.000000000 +0100 @@ -776,6 +776,52 @@ $self next "v" } +########### +# DAMA MODIFICATIONS +########## + +Node/SatNode instproc attach-profile {profile {index_ 0}} { + $self instvar mac_ ifq_ phy_tx_ + if {[info exist mac_]} { + $profile set_mac $mac_($index_) + $profile set_q $ifq_($index_) + $profile init_buffer [$mac_($index_) set dama_L_] + $mac_($index_) add_to_list $profile + $mac_($index_) refresh [$profile set cra_] + } + return $ifq_($index_) +} + +Node/SatNode instproc get_mac {t_id_} { + $self instvar mac_ + set mac_ref $mac_($t_id_) + return $mac_ref + } + +Node/SatNode instproc get_ifq {t_id_} { + $self instvar ifq_ + set ifq_ref $ifq_($t_id_) + return $ifq_ref + } + +DamaTerminalProfile set cra_ 1; +DamaTerminalProfile set rbdc_ 0; +DamaTerminalProfile set vbdc_ 0; +Mac/Sat/Dama set extradelay_ 0; +Mac/Sat/Dama set slot_ 1; +Mac/Sat/Dama set bytes_per_superframe_ 0; +Mac/Sat/Dama set superframe_duration_ 100 +Mac/Sat/Dama set slot_per_frame_ 32 +Mac/Sat/Dama set frame_per_superframe_ 1 +DamaTerminalProfile set terminal_id_ 0 +DamaTerminalProfile set dama_L_ 0 +DamaTerminalProfile set rbdc_gamma_ 0.2 + +Queue/DropTail set backlog_ 0; + +########################## + + # ====================================================================== #