Wednesday, April 16, 2008

Tdma-dama patch for ns-2.32

--- ns-allinone-2.32.bak/ns-2.32/mac/mac-bod.cc 1970-01-01 10:00:00.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/mac/mac-bod.cc 2008-04-15 17:43:11.000000000 +1000
@@ -0,0 +1,435 @@
+// Copyright (c) 2006 by the Consiglio Nazionale Ricerche (CNR) area 
+// della Ricerca di Pisa
+// 
+// All rights reserved.
+//
+// Permission to use, copy, modify, and distribute this software and its
+// documentation in source and binary forms for non-commercial purposes
+// and without fee is hereby granted, provided that the above copyright
+// notice appear in all copies and that both the copyright notice and
+// this permission notice appear in supporting documentation. and that
+// any documentation, advertising materials, and other materials related
+// to such distribution and use acknowledge that the software was
+// developed by the University of Southern California, Information
+// Sciences Institute.  The name of the University may not be used to
+// endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THE Consiglio Nazionale Ricerche (CNR) makes no representations about
+// the suitability of this software for any purpose.  THIS SOFTWARE IS
+// PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+// INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Other copyrights might apply to parts of this software and are so
+// noted when applicable.
+//
+//
+// mac-bod.cc
+// by Raffaello Secchi (raffaello.secchi@isti.cnr.it), CNR/ISTI
+
+
+#include "delay.h"
+#include "connector.h"
+#include "packet.h"
+#include "random.h"
+
+#include "arp.h"
+#include "ll.h"
+#include "mac.h"
+#include "mac-tdma.h"
+#include "cmu-trace.h"
+
+/* Initialize Requester and Allocator*/ 
+TdmaRequester::TdmaRequester():  qMon_(0) 
+{
+ bind("request_",&request_);
+}
+
+
+TdmaAllocator::TdmaAllocator()
+{
+ bind("delay_",&delay_);
+ bind("active_node_",&active_node_);
+ bind("max_slot_num_",&max_slot_num_);
+ schedule_nxt_ = NULL;
+}
+
+AllocatorProportional::AllocatorProportional(): TdmaAllocator()
+{
+ deficit = 0; 
+ slot_index = 0;
+}
+
+
+/* ======================================================================
+   TCL Hooks for the simulator
+   ====================================================================== */
+
+static class AllocatorProportionalClass : public TclClass {
+public:
+ AllocatorProportionalClass() : TclClass("Allocator/Proportional") {}
+ TclObject* create(int, const char*const*) {
+  return (new AllocatorProportional());
+ }
+} class_allocator_proportional;
+
+static class AllocatorTclClass : public TclClass {
+public:
+ AllocatorTclClass() : TclClass("Allocator/Tcl") {}
+ TclObject* create(int, const char*const*) {
+  return (new AllocatorTcl());
+ }
+} class_allocator_tcl;
+
+static class RequesterConstantClass : public TclClass {
+public:
+ RequesterConstantClass() : TclClass("Requester/Constant") {}
+ TclObject* create(int, const char*const*) {
+  return (new RequesterConstant());
+ }
+} class_requester_constant;
+
+static class RequesterRBDCClass : public TclClass {
+public:
+ RequesterRBDCClass() : TclClass("Requester/RBDC") {}
+ TclObject* create(int, const char*const*) {
+  return (new RequesterRBDC());
+ }
+} class_requester_rbdc;
+
+static class RequesterVBDCClass : public TclClass {
+public:
+ RequesterVBDCClass() : TclClass("Requester/VBDC") {}
+ TclObject* create(int, const char*const*) {
+  return (new RequesterVBDC());
+ }
+} class_requester_vbdc;
+
+static class RequesterTclClass : public TclClass {
+public:
+ RequesterTclClass() : TclClass("Requester/Tcl") {}
+ TclObject* create(int, const char*const*) {
+  return (new RequesterTcl());
+ }
+} class_requester_tcl;
+
+
+/* Reinitialize Allocator and Requester objects after new nodes is created */
+void TdmaAllocator::init() {
+ 
+ requestv_ = mac_->requestv_;
+ max_slot_num_ = mac_->max_slot_num_;
+ tdma_schedule_nxt_ = mac_->tdma_schedule_nxt_;
+ if (schedule_nxt_)
+  delete [] schedule_nxt_;
+ schedule_nxt_ = new int[max_slot_num_];
+ active_node_ = mac_->active_node_;
+
+ mac_->allocator_ = this;
+
+}
+
+void AllocatorProportional::init(){
+
+ if (deficit) 
+  delete[] deficit;
+  
+ active_node_ = mac_->active_node_;
+
+ deficit = new double[active_node_];
+ for(int i=0; i<active_node_; i++)
+  deficit[i] = 0; 
+
+ TdmaAllocator::init();
+}
+
+void AllocatorTcl::init(){
+ 
+ Tcl& tcl = Tcl::instance();
+
+ active_node_ = mac_->active_node_;
+
+ // initialize AllocatorTcl instvars
+ tcl.evalf("%s initvar",name());
+
+ TdmaAllocator::init();
+}
+
+void TdmaRequester::init() {
+ requestv_ = mac_->requestv_;
+ slot_num_ = mac_->slot_num_;
+ mac_->requester_ = this;
+}
+
+void RequesterTcl::init() {
+ 
+ Tcl& tcl = Tcl::instance();
+
+ // initialize RequesterTcl instvars
+ tcl.evalf("%s initvar",name());
+ 
+ TdmaRequester::init();
+}
+
+
+/* ======================================================================
+   Command Interface with the interpreter 
+   ====================================================================== */
+int AllocatorProportional::command(int argc, const char*const* argv)
+{
+
+ if (argc == 3) {
+  if (strcmp(argv[1], "attach") == 0) {
+   mac_ = (MacTdma*) TclObject::lookup(argv[2]);
+   if(mac_ == 0)
+    return TCL_ERROR;
+   init();
+   return TCL_OK;
+  }
+ }
+ return TdmaAllocator::command(argc, argv);
+}
+
+int AllocatorTcl::command(int argc, const char*const* argv)
+{
+
+ if (argc == 3) {
+  if (strcmp(argv[1], "attach") == 0) {
+   mac_ = (MacTdma*) TclObject::lookup(argv[2]);
+   if(mac_ == 0)
+    return TCL_ERROR;
+   init();
+   return TCL_OK;
+  }
+ }
+ return TdmaAllocator::command(argc, argv);
+}
+
+
+int TdmaRequester::command(int argc, const char*const* argv){
+ 
+ if (argc == 3) {
+  if (strcmp(argv[1], "attach") == 0) {
+   mac_ = (MacTdma*) TclObject::lookup(argv[2]);
+   if(mac_ == 0)
+    return TCL_ERROR;
+   init(); 
+   return TCL_OK;
+  }
+  if (strcmp(argv[1], "setifq") == 0) {
+   ifq_ = (Queue *)TclObject::lookup(argv[2]);
+   if (!ifq_)
+    return TCL_ERROR;
+   return (TCL_OK);
+  }
+  if (strcmp(argv[1], "setmon") == 0) {
+   qMon_ = (QueueMonitor *)TclObject::lookup(argv[2]);
+   if (!qMon_)
+    return TCL_ERROR;
+   return (TCL_OK);
+  }
+ }
+ return TclObject::command(argc,argv);
+}
+
+int RequesterConstant::command(int argc, const char*const* argv)
+{
+ return TdmaRequester::command(argc, argv);
+}
+
+int RequesterRBDC::command(int argc, const char*const* argv)
+{
+ return TdmaRequester::command(argc, argv);
+}
+
+int RequesterVBDC::command(int argc, const char*const* argv)
+{
+ return TdmaRequester::command(argc, argv);
+}
+
+int RequesterTcl::command(int argc, const char*const* argv)
+{
+ if (argc == 3) {
+  if (strcmp(argv[1], "attach") == 0) {
+   mac_ = (MacTdma*) TclObject::lookup(argv[2]);
+   if(mac_ == 0)
+    return TCL_ERROR;
+   init(); 
+   return TCL_OK;
+  }
+ }
+ return TdmaRequester::command(argc, argv);
+}
+
+
+/* ======================================================================
+   Debugging Routines
+   ====================================================================== */
+
+void TdmaAllocator::printrequests(){
+
+ for(int i=0; i<active_node_ ; i++ )
+    printf("[%d]",requestv_[i]);
+ printf("\n");
+
+}
+
+void TdmaAllocator::printrequest_nxt(){
+ for(int i=0; i<max_slot_num_ ; i++ )
+    if (schedule_nxt_[i] == SLOT_UNALLOC)
+   printf("[N]");
+  else
+   printf("[%d]", schedule_nxt_[i]);
+ printf("\n");
+}
+
+
+/* Requester Main Functions */
+
+void RequesterConstant::dorequest(){
+
+ /* overwrite previous request */
+ requestv_[slot_num_] = request_;
+}
+
+void RequesterRBDC::dorequest(){
+
+ rate = (qMon_->barrivals() - pin)/(mac_->slot_packet_len_*mac_->num_frame_);
+ 
+ /* overwrite previous request */
+ requestv_[slot_num_] = rate+1;
+
+ pin = qMon_->barrivals();
+ tin = NOW;
+}
+
+void RequesterVBDC::dorequest(){
+
+ buffer = qMon_->barrivals() - qMon_->bdepartures() - qMon_->bdrops();
+ /* overwrite previous request */
+ printf("%lf %d %d\n",NOW, slot_num_, 
+   buffer/(mac_->slot_packet_len_*mac_->num_frame_));
+ requestv_[slot_num_] = buffer/(mac_->slot_packet_len_*mac_->num_frame_)+1;
+}
+
+void RequesterTcl::dorequest(){
+
+ char wrk[1024];
+ Tcl& tcl = Tcl::instance();
+ 
+ // call the requester tcl
+ sprintf(wrk,"%s dorequest",name());
+ tcl.evalc(wrk);
+
+ /* overwrite previous request */
+ requestv_[slot_num_] = atoi(tcl.result());
+ 
+}
+
+
+/* Main Allocation  Functions */
+void TdmaAllocator::allocation(){
+
+ /* create new timer */
+ copy_ = new AllocationDelay(this);
+
+ /* store schedule_nxt to local memory */
+ copy_->schedule_ = new int[max_slot_num_];
+
+ for(int i=0; i<max_slot_num_; i++)
+  copy_->schedule_[i] = schedule_nxt_[i];
+ 
+ /* schedule the allocation */
+ copy_->sched(delay_);
+        
+ mac_->trace_event("reques",0);
+ mac_->trace_event("nxt",0);
+
+}
+
+void TdmaAllocator::schedule_copy(AllocationDelay* c){
+ 
+ /* copy the sent schedule to local MAC */
+ for(int i=0; i<max_slot_num_; i++)
+  tdma_schedule_nxt_[i] = c->schedule_[i];
+
+ /* free memory */
+ delete c;
+}
+
+/* Implements the Proportional */
+void AllocatorProportional::allocation() 
+{
+ int totreq = 0;  // sum of all requests
+ int slot = 0; 
+ int ns = 0;
+ int si = slot_index;
+ 
+ // find the sum of all requests
+ for(int i=0; i<active_node_; i++)
+    totreq += requestv_[i];
+
+ // add the previous deficit to current request
+ if ( totreq > 0 )
+    for(int i=0; i<active_node_; i++) 
+       if (i!=slot_index)
+   deficit[i] += double(max_slot_num_*requestv_[i])/totreq;
+   
+ while( slot<max_slot_num_ && ns<active_node_ ) {
+ 
+     while( ns<active_node_ && deficit[slot_index]<=EPS ) {
+  slot_index = (slot_index + 1) % active_node_;
+  ns++;
+     }
+
+     while( slot<max_slot_num_ && deficit[slot_index]>EPS ) {
+         deficit[slot_index]--;
+         schedule_nxt_[slot] = slot_index;
+         slot++;
+     }
+ }
+
+ deficit[si] += double(max_slot_num_*requestv_[si])/totreq;
+
+ // the rest is not allocated
+ if (slot<max_slot_num_)
+    for(int i=slot; i<max_slot_num_; i++)
+       if (deficit[si]>EPS) {
+   deficit[si]--;
+   schedule_nxt_[i] = si; 
+       } else 
+          schedule_nxt_[i] = SLOT_UNALLOC;
+
+ /* operation common to all Allocators */
+ TdmaAllocator::allocation();
+}
+
+
+
+/* Implements the Tcl Embedded allocation function */ 
+void AllocatorTcl::allocation() 
+{
+ Tcl & tcl = Tcl::instance();
+
+ char wrk[1024];
+ 
+ // initialize the array
+ for(int i=0; i<active_node_; i++)
+  tcl.evalf("%s set requestv_(%d) %d",name(),i,requestv_[i]);
+
+ // call Tcl scheduling function
+ tcl.evalf("%s allocation", name());
+
+ for(int i=0; i<max_slot_num_; i++){
+  sprintf(wrk,"%s set schedule_(%d)",name(),i);
+  tcl.evalc(wrk);
+  schedule_nxt_[i] = atoi(tcl.result());
+ }
+ 
+ // operation common to all Allocators 
+ TdmaAllocator::allocation();
+}
+
+
+
--- ns-allinone-2.32.bak/ns-2.32/mac/mac-tdma.h 2008-04-15 17:39:53.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/mac/mac-tdma.h 2008-04-15 17:43:11.000000000 +1000
@@ -1,4 +1,3 @@
-
 /*
  * mac-tdma.h
  * Copyright (C) 1999 by the University of Southern California
@@ -59,6 +58,8 @@
 //#include <debug.h>
 
 #include "marshall.h"
+#include "queue-monitor.h"
+
 #include <delay.h>
 #include <connector.h>
 #include <packet.h>
@@ -84,6 +85,8 @@
 #define DSSS_PreambleLength  144  // 144 bits
 #define DSSS_PLCPHeaderLength  48  // 48 bits
 
+#define EPS                             0.0000001
+
 class PHY_MIB {
 public:
  u_int32_t CWMin;
@@ -129,6 +132,11 @@
 /* Quoted from MAC-802.11. */
 #define DATA_DURATION           5
 
+// Indicate that the slot is not allocated 
+#define SLOT_UNALLOC             -2
+#define SLOT_NOREQ               0
+
+
 /* We are using same header structure as 802.11 currently */
 struct frame_control {
  u_char  fc_subtype  : 4;
@@ -174,9 +182,171 @@
  u_int32_t seqno;
 };
 
-/* Timers */
+
 class MacTdma;
 
+
+/* Make a request to allocator for each Tdma node */
+class TdmaRequester: public TclObject {
+
+public:
+ TdmaRequester();
+ virtual void dorequest() {};
+
+ int command(int argc, const char*const* argv);
+ 
+ // initialize dynamic variables
+ void init();
+
+ /* pointer to Queue */
+   Queue* ifq_;
+ QueueMonitor* qMon_;
+ 
+
+protected:
+ MacTdma* mac_;
+ int slot_num_;
+ int *requestv_;
+
+       /* the request to submit */
+ int request_;
+
+};
+
+
+class RequesterConstant: public TdmaRequester {
+
+public:
+ RequesterConstant(): TdmaRequester() { };
+ int command(int argc, const char*const* argv);
+ 
+ virtual void dorequest();
+
+};
+
+class RequesterRBDC: public TdmaRequester {
+
+public:
+ RequesterRBDC(): TdmaRequester() { };
+ int command(int argc, const char*const* argv);
+ 
+ virtual void dorequest();
+ 
+private:
+ int rate;
+        int pin;
+ double tin;
+};
+
+class RequesterVBDC: public TdmaRequester {
+
+public:
+ RequesterVBDC(): TdmaRequester() { };
+ int command(int argc, const char*const* argv);
+ 
+ virtual void dorequest();
+
+private:
+       int buffer;
+};
+
+class RequesterTcl: public TdmaRequester {
+
+public:
+ RequesterTcl(): TdmaRequester() { };
+ int command(int argc, const char*const* argv);
+ 
+ virtual void dorequest();
+
+ void init();
+};
+
+class AllocationDelay;
+
+/* Allocator classes */
+class TdmaAllocator: public TclObject {
+friend class AllocationDelay;
+
+public:
+ TdmaAllocator();
+ int command(int argc, const char*const* argv){ 
+  return TclObject::command(argc,argv); 
+ };
+
+ void virtual allocation();
+ int active_node_;
+ int max_slot_num_;
+ 
+ void virtual init();
+ int *schedule_nxt_;
+
+protected:
+ MacTdma* mac_;
+ 
+ /* request vector */
+ int *requestv_;
+ int *tdma_schedule_nxt_;
+ void printrequests();
+ void printrequest_nxt();
+
+ /* allocation delay */
+ double delay_;
+ double jitter_;
+
+ AllocationDelay* copy_;
+ void schedule_copy(AllocationDelay *);
+ 
+};
+
+/* implements the timer that copy next allocation */
+class AllocationDelay: public TimerHandler {
+public:
+ AllocationDelay(TdmaAllocator* a): TimerHandler() {
+  allocator_ = a;
+ }
+ int * schedule_;
+ 
+ virtual void expire(Event *e){
+  allocator_->schedule_copy(this);
+ }
+ 
+ ~AllocationDelay() {
+  delete [] schedule_;
+ }
+
+protected:
+ TdmaAllocator* allocator_;
+};
+
+class AllocatorProportional: public TdmaAllocator {
+
+public:
+ AllocatorProportional();
+ int command(int argc, const char*const* argv);
+ virtual void allocation();
+ void virtual init();
+ 
+protected:
+   double* deficit;           // deficit for allocator
+ int slot_index;
+ double creq;
+};
+
+class AllocatorTcl: public TdmaAllocator {
+
+public:
+ AllocatorTcl(): TdmaAllocator() {} ;
+ int command(int argc, const char*const* argv);
+ virtual void allocation();
+ void virtual init();
+protected:
+ int slot_index;
+ 
+};
+
+
+/* Timers */
+
 class MacTdmaTimer : public Handler {
 public:
  MacTdmaTimer(MacTdma* m, double s = 0) : mac(m) {
@@ -235,7 +405,8 @@
   friend class SlotTdmaTimer;
   friend class TxPktTdmaTimer;
   friend class RxPktTdmaTimer;
-
+  friend class TdmaAllocator;
+  
  public:
   MacTdma(PHY_MIB* p);
   void  recv(Packet *p, Handler *h);
@@ -248,17 +419,47 @@
   void recvHandler(Event *e);
   void sendHandler(Event *e);
   
- protected:
-  PHY_MIB  *phymib_;
+  static int *requestv_;             // The vector of requests done by stations
   
-  // Both the slot length and max slot num (max node num) can be configged.
+  /* Requester and Allocator objects for slot scheduling */
+  static TdmaAllocator* allocator_;
+  TdmaRequester* requester_;
+
+  /* Data structure for tdma scheduling. */
+  static int active_node_;            // How many nodes needs to be descheduled
+
+  static int *tdma_schedule_nxt_;     // The next frame to allocate
+  
+  /* TDMA scheduling state. 
+     Currently, we only use a centralized simplified way to do 
+     scheduling. Will work on the algorithm later.*/
+  // The max num of slot within one frame.
+  static int max_slot_num_;
+  int slot_num_;                      // The slot number it's allocated.
+ 
+  /* MAC Trace support */
+  EventTrace* et_;
+  virtual void trace_event(char* event,int val);
+ 
+  
+ // Both the slot length and max slot num (max node num) can be configged.
   int   slot_packet_len_;
-  int                   max_node_num_;
+ 
+ // The number of frame after which a request is done
+  static int num_frame_;
+ 
+ protected:
+  PHY_MIB  *phymib_;
   
+
  private:
   int command(int argc, const char*const* argv);
 
+  // dump only allocation
+  int dump_alloc_;
+  
   // Do slot scheduling for the active nodes within one cluster.
+  void re_allocate();
   void re_schedule();
   void makePreamble();
   void radioSwitch(int i);
@@ -282,14 +483,9 @@
     logtarget_->recv(p, (Handler*) 0);
   }
   
-  inline double TX_Time(Packet *p) {
-    double t = DATA_Time((HDR_CMN(p))->size());
-
-    //    printf("<%d>, packet size: %d, tx-time: %f\n", index_, (HDR_CMN(p))->size(), t);
-    if(t < 0.0) {
-      drop(p, "XXX");
-      exit(1);
-    }
+  inline double TX_Time() {
+    double t = DATA_Time(residue_);
+    
     return t;
   }
   
@@ -303,7 +499,8 @@
   TxPktTdmaTimer mhTxPkt_;
   RxPktTdmaTimer mhRxPkt_;
 
-  /* Internal MAC state */
+
+   /* Internal MAC state */
   MacState rx_state_; // incoming state (MAC_RECV or MAC_IDLE)
   MacState tx_state_; // outgoing state
   
@@ -314,42 +511,36 @@
   
   NsObject* logtarget_;
   
-  /* TDMA scheduling state. 
-     Currently, we only use a centralized simplified way to do 
-     scheduling. Will work on the algorithm later.*/
-  // The max num of slot within one frame.
-  static int max_slot_num_;
-
+  int frame_;
+  
   // The time duration for each slot.
   static double slot_time_;
 
   /* The start time for whole TDMA scheduling. */
   static double start_time_;
-  
-  /* Data structure for tdma scheduling. */
-  static int active_node_;            // How many nodes needs to be scheduled
 
+  /* initial slot time */
+  double slot_start_time_;
+  
   static int *tdma_schedule_;
-  int slot_num_;                      // The slot number it's allocated.
 
   static int *tdma_preamble_;        // The preamble data structure.
-
+    
   // When slot_count_ = active_nodes_, a new preamble is needed.
   int slot_count_;
+ 
+  // The remaining part of packet to send
+  int residue_;
+  
+  // number of request received during active frame
+  static int num_requests_;
   
   // How many packets has been sent out?
   static int tdma_ps_;
   static int tdma_pr_;
-};
-
-double MacTdma::slot_time_ = 0;
-double MacTdma::start_time_ = 0;
-int MacTdma::active_node_ = 0;
-int MacTdma::max_slot_num_ = 0;
-int *MacTdma::tdma_schedule_ = NULL;
-int *MacTdma::tdma_preamble_ = NULL;
+  
+  void watch_alloc();
 
-int MacTdma::tdma_ps_ = 0;
-int MacTdma::tdma_pr_ = 0;
+};
 
 #endif /* __mac_tdma_h__ */
--- ns-allinone-2.32.bak/ns-2.32/mac/mac-tdma.cc 2008-04-15 17:39:53.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/mac/mac-tdma.cc 2008-04-15 17:43:11.000000000 +1000
@@ -83,6 +83,21 @@
  tx_state_ = (x);    \
 }
 
+double MacTdma::slot_time_ = 0;
+double MacTdma::start_time_ = 0;
+int MacTdma::active_node_ = 0;
+int MacTdma::max_slot_num_ = 0;
+int MacTdma::num_requests_ = 0;
+int *MacTdma::tdma_schedule_ = NULL;
+int *MacTdma::tdma_preamble_ = NULL;
+int *MacTdma::tdma_schedule_nxt_ = NULL;
+int *MacTdma::requestv_ = NULL;
+TdmaAllocator *MacTdma::allocator_ = NULL;
+int  MacTdma::num_frame_ = 1;
+
+int MacTdma::tdma_ps_ = 0;
+int MacTdma::tdma_pr_ = 0;
+
 /* Phy specs from 802.11 */
 static PHY_MIB PMIB = {
  DSSS_CWMin, DSSS_CWMax, DSSS_SlotTime, DSSS_CCATime,
@@ -90,6 +105,7 @@
  DSSS_PLCPHeaderLength
 }; 
 
+
 /* Timers */
 void MacTdmaTimer::start(Packet *p, double time)
 {
@@ -101,12 +117,15 @@
  stime = s.clock();
  rtime = time;
  assert(rtime >= 0.0);
-  
+  
+        
  s.schedule(this, p, rtime);
+
 }
 
 void MacTdmaTimer::stop(Packet *p) 
 {
+
  Scheduler &s = Scheduler::instance();
  assert(busy_);
   
@@ -155,9 +174,6 @@
  mac->sendHandler(e);
 }
 
-/* ======================================================================
-   TCL Hooks for the simulator
-   ====================================================================== */
 static class MacTdmaClass : public TclClass {
 public:
  MacTdmaClass() : TclClass("Mac/Tdma") {}
@@ -171,43 +187,55 @@
 // Frame format:
 // Pamble Slot1 Slot2 Slot3...
 MacTdma::MacTdma(PHY_MIB* p) : 
- Mac(), mhSlot_(this), mhTxPkt_(this), mhRxPkt_(this){
+ Mac(), requester_(0), et_(0), dump_alloc_(0), 
+ mhSlot_(this), mhTxPkt_(this),  mhRxPkt_(this) {
+
  /* Global variables setting. */
  // Setup the phy specs.
+ static int slot_pointer = 0;
+
  phymib_ = p;
- 
- /* Get the parameters of the link (which in bound in mac.cc, 2M by default),
-    the packet length within one TDMA slot (1500 byte by default), 
-    and the max number of nodes (64) in the simulations.*/
+
+ // bind parameters of MacTdma object
  bind("slot_packet_len_", &slot_packet_len_);
- bind("max_node_num_", &max_node_num_);
+ bind("max_slot_num_", &max_slot_num_);
+ bind("num_frame_", &num_frame_);
+ bind("dump_alloc_", &dump_alloc_);
+ 
  
- //  slot_packet_len_ = 1500;
- //  max_node_num_ = 64;
  // Calculate the slot time based on the MAX allowed data length.
  slot_time_ = DATA_Time(slot_packet_len_);
  
- /* Calsulate the max slot num within on frame from max node num.
-    In the simple case now, they are just equal. 
- */
- max_slot_num_ = max_node_num_;
  
- /* Much simplified centralized scheduling algorithm for single hop
-    topology, like WLAN etc. 
+ 
+ // Initialize the tdma schedule data structures.
+ if ( !tdma_schedule_ ) {
+  tdma_schedule_ = new int[max_slot_num_];
+  tdma_preamble_ = new int[max_slot_num_];
+  tdma_schedule_nxt_ = new int[max_slot_num_];
+  requestv_ = new int[max_slot_num_];
+
+  for(int i=active_node_; i<max_slot_num_; i++) {
+   tdma_preamble_[i] = NOTHING_TO_SEND;
+   tdma_schedule_[i] = SLOT_UNALLOC;
+   tdma_schedule_nxt_[i] = SLOT_UNALLOC;
+   requestv_[i] = SLOT_NOREQ;
+  }
+ }
+
+ /*
+ if ( active_node_ < max_slot_num_) {
+  tdma_preamble_[active_node_] = active_node_;
+  tdma_schedule_[active_node_] = active_node_;
+  tdma_schedule_nxt_[active_node_] = active_node_;
+ }
  */
- // Initualize the tdma schedule and preamble data structure.
- tdma_schedule_ = new int[max_slot_num_];
- tdma_preamble_ = new int[max_slot_num_];
 
- /* Do each node's initialization. */
  // Record the initial active node number.
  active_node_++;
-
- if (active_node_ > max_node_num_) {
-  printf("Too many nodes taking part in the simulations, aborting...\n");
-  exit(-1);
- }
-    
+ 
+ /* Do each node's initialization. */
+ 
  // Initial channel / transceiver states. 
  tx_state_ = rx_state_ = MAC_IDLE;
  tx_active_ = 0;
@@ -215,16 +243,28 @@
  // Initialy, the radio is off. NOTE: can't use radioSwitch(OFF) here.
  radio_active_ = 0;
 
- // Do slot scheduling.
- re_schedule();
+ // Record the start time of the new schedule.
+ start_time_ = NOW;
+
+ /* Seperate slot_num_ and the node id: 
+    we may have flexibility as node number changes.
+ */
+ slot_num_ = slot_pointer++;
+ 
+ frame_ = 0;
 
+ if ( allocator_ )
+  allocator_->init();
+  
  /* Deal with preamble. */
  // Can't send anything in the first frame.
  slot_count_ = FIRST_ROUND;
- tdma_preamble_[slot_num_] = NOTHING_TO_SEND;
+ 
+ residue_ = 0;
+ 
+ //Start the Slot timer...
+ mhSlot_.start((Packet *) (& intr_), 0);
 
- //Start the Slot timer..
- mhSlot_.start((Packet *) (& intr_), 0);  
 }
 
 /* similar to 802.11, no cached node lookup. */
@@ -237,13 +277,19 @@
     return TCL_ERROR;
    return TCL_OK;
   }
+  if (strcmp(argv[1], "eventtrace") == 0) {
+   et_ = (EventTrace *)TclObject::lookup(argv[2]);
+   if (!et_)
+    return TCL_ERROR;
+   return (TCL_OK);
+  }
  }
  return Mac::command(argc, argv);
 }
 
 
 /* ======================================================================
-   Debugging Routines
+   Debugging & Tracing Routines
    ====================================================================== */
 void MacTdma::trace_pkt(Packet *p) 
 {
@@ -268,12 +314,118 @@
   (long) pktTx_, (long) pktRx_, (long) callback_);
 }
 
+void MacTdma::watch_alloc(){
+ 
+ for(int i=0; i<max_slot_num_; i++)
+  if (tdma_schedule_[i] == SLOT_UNALLOC)
+   printf("[N]");
+  else
+   printf("[%d]",tdma_schedule_[i]);
+ printf("\n"); 
+
+}
+
+
+void MacTdma::trace_event(char *event, int val)
+{
+ 
+ if (et_ == NULL) return;
+ char *wrk = et_->buffer();
+ 
+ if (dump_alloc_)
+    if ( strcmp(event,"req") != 0 &&
+  strcmp(event,"nxt") != 0 && 
+  strcmp(event,"cur") != 0 )
+  return;
+  
+ if (wrk != 0) {
+    if (strcmp(event,"cur") == 0) {
+       static int *xc = new int[active_node_];
+       for(int i=0; i<active_node_; i++)
+     xc[i] = 0;
+       sprintf(wrk, "<%d> %lf %sslt ", index_, NOW, event);
+       for(int i=0; i<max_slot_num_; i++)
+   if (tdma_schedule_[i] == SLOT_UNALLOC)
+      sprintf(wrk+strlen(wrk), "[N]");
+   else{
+      sprintf(wrk+strlen(wrk), "[%d]", tdma_schedule_[i]);
+      xc[tdma_schedule_[i]]++;
+   }
+       sprintf(wrk+strlen(wrk), "\n<%d> %lf %sall ", index_, NOW, event);
+       for(int i=0; i<active_node_; i++)
+     sprintf(wrk+strlen(wrk), "%d ", xc[i]);
+    } else if (strcmp(event,"reques") == 0) {
+       sprintf(wrk, "<%d> %lf %s ", index_, NOW, event);
+       for(int i=0; i<active_node_; i++ )
+   sprintf(wrk+strlen(wrk),"%d ",requestv_[i]);
+    } else if (strcmp(event,"nxt") == 0) {
+       static int *xs = new int[active_node_];
+       for(int i=0; i<active_node_; i++)
+     xs[i] = 0;
+       sprintf(wrk, "<%d> %lf %sslt ", index_, NOW, event);
+       for(int i=0; i<max_slot_num_; i++ )
+     if (allocator_->schedule_nxt_[i] == SLOT_UNALLOC)
+     sprintf(wrk+strlen(wrk), "[N]");
+  else{
+     sprintf(wrk+strlen(wrk), "[%d]", allocator_->schedule_nxt_[i]);
+     xs[allocator_->schedule_nxt_[i]]++;
+  }
+       sprintf(wrk+strlen(wrk), "\n<%d> %lf %sall ", index_, NOW, event);
+       for(int i=0; i<active_node_; i++)
+     sprintf(wrk+strlen(wrk), "%d ", xs[i]);
+    } else if (strcmp(event,"req") == 0) {
+       static double *prev = new double[active_node_];
+       static int   *prevb = new int [active_node_];
+       static int flg = 0;
+       //
+       
+       if (!flg) {
+             for(int i=0; i<active_node_; i++){
+    prev[i] = 0.0;
+    prevb[i] = 0;
+        }
+          flg = 1;
+       }
+
+       int queue;
+           
+       double dt = 0;
+       double db = 0;
+             
+       dt = NOW - prev[index_];
+       
+       
+       db = 8*((int)requester_->qMon_->barrivals() - 
+            (int)requester_->qMon_->bdrops()-prevb[index_]);
+
+       prevb[index_] = (int)requester_->qMon_->barrivals() - 
+                       (int)requester_->qMon_->bdrops();
+  
+       queue = (int)requester_->qMon_->barrivals() - 
+        (int)requester_->qMon_->bdepartures() -
+               (int)requester_->qMon_->bdrops();
+       
+
+       sprintf(wrk, "<%d> %lf reqpar %d %lf", index_, NOW,
+      queue,db/dt);
+       
+       prev[index_] = NOW;
+       
+    } else 
+       sprintf(wrk, "<%d> %lf %s %d", index_, NOW, event, val);
+ }
+
+ et_->trace();
+}
+
 
 /* ======================================================================
    Packet Headers Routines
    ====================================================================== */
+
 int MacTdma::hdr_dst(char* hdr, int dst )
 {
+
  struct hdr_mac_tdma *dh = (struct hdr_mac_tdma*) hdr;
  if(dst > -2)
   STORE4BYTE(&dst, (dh->dh_da));
@@ -282,6 +434,7 @@
 
 int MacTdma::hdr_src(char* hdr, int src )
 {
+
  struct hdr_mac_tdma *dh = (struct hdr_mac_tdma*) hdr;
  if(src > -2)
   STORE4BYTE(&src, (dh->dh_sa));
@@ -306,85 +459,103 @@
  return 1;
 }
 
-/* Do the slot re-scheduling:
-   The idea of postphone the slot scheduling for one slot time may be useful.
-*/
+/* Do slot re-scheduling */
 void MacTdma::re_schedule() {
- static int slot_pointer = 0;
- // Record the start time of the new schedule.
- start_time_ = NOW;
- /* Seperate slot_num_ and the node id: 
-    we may have flexibility as node number changes.
- */
- slot_num_ = slot_pointer++;
- tdma_schedule_[slot_num_] = (char) index_;
+
+ /* make the requests */
+ if (frame_ == 0 && requester_) {
+  trace_event("req",slot_num_);
+  requester_->dorequest();
+ }
+
+ frame_ = (frame_ + 1) % num_frame_;
+
+ /* apply next schedule */
+ for(int i=0; i<max_slot_num_; i++)
+  tdma_schedule_[i] = tdma_schedule_nxt_[i];
+}
+
+/* Do slot re-allocation */
+void MacTdma::re_allocate() {
+
+ num_requests_++;
+
+ // printf("%lf %d %d\n", NOW, num_requests_, slot_num_);
+
+ if (num_requests_ < active_node_)
+  return;
+
+ if (allocator_)
+  allocator_->allocation();
+
+ trace_event("cur",0);
+
+ num_requests_ = 0;
 }
 
 /* To handle incoming packet. */
 void MacTdma::recv(Packet* p, Handler* h) {
  struct hdr_cmn *ch = HDR_CMN(p);
  
+ u_int32_t dst;
+ struct hdr_mac_tdma* dh;
+
  /* Incoming packets from phy layer, send UP to ll layer. 
     Now, it is in receiving mode. 
  */
  if (ch->direction() == hdr_cmn::UP) {
+  
+  dh = HDR_MAC_TDMA(p);  
+  dst = ETHER_ADDR(dh->dh_da);
+
   // Since we can't really turn the radio off at lower level, 
-  // we just discard the packet.
-  if (!radio_active_) {
-   free(p);
-   //printf("<%d>, %f, I am sleeping...\n", index_, NOW);
+  // we just discard the packet when is not directed to us
+  // or is broadcast
+  if (dst != (u_int32_t) index_ && dst != MAC_BROADCAST) {
+   Packet::free(p);
    return;
   }
 
   sendUp(p);
-  //printf("<%d> packet recved: %d\n", index_, tdma_pr_++);
   return;
+  
  }
- 
+
  /* Packets coming down from ll layer (from ifq actually),
     send them to phy layer. 
     Now, it is in transmitting mode. */
- callback_ = h;
+ 
+ callback_ = h; 
  state(MAC_SEND);
  sendDown(p);
- //printf("<%d> packet sent down: %d\n", index_, tdma_ps_++);
+
 }
 
 void MacTdma::sendUp(Packet* p) 
 {
- struct hdr_cmn *ch = HDR_CMN(p);
-
- /* Can't receive while transmitting. Should not happen...?*/
- if (tx_state_ && ch->error() == 0) {
-  printf("<%d>, can't receive while transmitting!\n", index_);
-  ch->error() = 1;
- };
 
  /* Detect if there is any collision happened. should not happen...?*/
  if (rx_state_ == MAC_IDLE) {
   SET_RX_STATE(MAC_RECV);     // Change the state to recv.
   pktRx_ = p;                 // Save the packet for timer reference.
 
-  /* Schedule the reception of this packet, 
-     since we just see the packet header. */
-  double rtime = TX_Time(p);
-  assert(rtime >= 0);
-
   /* Start the timer for receiving, will end when receiving finishes. */
-  mhRxPkt_.start(p, rtime);
+  mhRxPkt_.start(p, 0);
  } else {
   /* Note: we don't take the channel status into account, 
      as collision should not happen...
   */
   printf("<%d>, receiving, but the channel is not idle....???\n", index_);
  }
+
 }
 
 /* Actually receive data packet when RxPktTimer times out. */
 void MacTdma::recvDATA(Packet *p){
+
  /*Adjust the MAC packet size: strip off the mac header.*/
  struct hdr_cmn *ch = HDR_CMN(p);
- ch->size() -= ETHER_HDR_LEN;
+ // ch->size() -= ETHER_HDR_LEN;
  ch->num_forwards() += 1;
 
  /* Pass the packet up to the link-layer.*/
@@ -395,17 +566,20 @@
    Need to calculate a certain time slot for transmission. */
 void MacTdma::sendDown(Packet* p) {
  u_int32_t dst, src, size;
-  
+
+ int send_byte;
+
  struct hdr_cmn* ch = HDR_CMN(p);
  struct hdr_mac_tdma* dh = HDR_MAC_TDMA(p);
 
  /* Update the MAC header, same as 802.11 */
- ch->size() += ETHER_HDR_LEN;
+ // ch->size() += ETHER_HDR_LEN;
 
+ 
  dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;
  dh->dh_fc.fc_type       = MAC_Type_Data;
  dh->dh_fc.fc_subtype    = MAC_Subtype_Data;
- 
+
  dh->dh_fc.fc_to_ds      = 0;
  dh->dh_fc.fc_from_ds    = 0;
  dh->dh_fc.fc_more_frag  = 0;
@@ -424,8 +598,30 @@
  src = ETHER_ADDR(dh->dh_sa);
  size = ch->size();
 
+
+ if (pktTx_ != NULL)
+  printf("<%d> warning: buffer is NOT empty\n",index_);
+
+
  /* buffer the packet to be sent. */
  pktTx_ = p;
+
+ /* initialize the residue to whole packet length */ 
+ residue_ = (HDR_CMN(pktTx_))->size();
+ // printf("residue = %d\n",residue_);
+
+ if (slot_count_ >= 0 && tdma_schedule_[slot_count_] == slot_num_ && is_idle()){ 
+  send_byte = slot_packet_len_-int((NOW - slot_start_time_)*bandwidth_/8.0);
+  if (residue_ <= send_byte) {
+   /* the packet can be sent immediately since is my turn,
+    * the MAC is idle and enough space is in slot*/ 
+   tdma_preamble_[slot_count_] = (char) dst;
+   send();
+   residue_ = 0;
+   return;
+  }
+  residue_ -= send_byte;
+ }
 }
 
 /* Actually send the packet. */
@@ -457,7 +653,7 @@
  dst = ETHER_ADDR(dh->dh_da);
  src = ETHER_ADDR(dh->dh_sa);
  size = ch->size();
- stime = TX_Time(pktTx_);
+ stime = TX_Time();
  ch->txtime() = stime;
  
  /* Turn on the radio and transmit! */
@@ -466,6 +662,7 @@
 
  /* Start a timer that expires when the packet transmission is complete. */
  mhTxPkt_.start(pktTx_->copy(), stime);
+ 
  downtarget_->recv(pktTx_, this);        
 
  pktTx_ = 0;
@@ -509,10 +706,10 @@
   dh = HDR_MAC_TDMA(pktTx_);  
   dst = ETHER_ADDR(dh->dh_da);
   //printf("<%d>, %f, write %d to slot %d in preamble\n", index_, NOW, dst, slot_num_);
-  tdma_preamble_[slot_num_] = dst;
+  tdma_preamble_[slot_count_] = dst;
  } else {
   //printf("<%d>, %f, write NO_PKT to slot %d in preamble\n", index_, NOW, slot_num_);
-  tdma_preamble_[slot_num_] = NOTHING_TO_SEND;
+  tdma_preamble_[slot_count_] = NOTHING_TO_SEND;
  }
 }
 
@@ -527,49 +724,64 @@
  // Restart timer for next slot.
  mhSlot_.start((Packet *)e, slot_time_);
 
- // Make a new presamble for next frame.
- if ((slot_count_ == active_node_) || (slot_count_ == FIRST_ROUND)) {
-  //printf("<%d>, %f, make the new preamble now.\n", index_, NOW);
+ slot_count_++;
+
+ // Make the new preamble for next frame.
+ if ((slot_count_ == max_slot_num_) || (slot_count_ == FIRST_ROUND)) {
+
+  /* call the requester at the beginning of frame */
+  re_schedule();
+
+  /* call the allocator at the beginning of frame */
+  re_allocate();
+
   // We should turn the radio on for the whole slot time.
   radioSwitch(ON);
 
-  makePreamble();
-  slot_count_ = 0;
+  slot_count_ = -1;
   return;
  }
 
  // If it is the sending slot for me.
- if (slot_count_ == slot_num_) {
-  //printf("<%d>, %f, time to send.\n", index_, NOW);
-  // We have to check the preamble first to avoid the packets coming in the middle.
-  if (tdma_preamble_[slot_num_] != NOTHING_TO_SEND)
-   send();
-  else
-   radioSwitch(OFF);
+ if (tdma_schedule_[slot_count_] == slot_num_) {
+ 
+  slot_start_time_ = NOW;
+
+  if (residue_ <= slot_packet_len_) {
+   
+   /* the packet can be sent immediately since is my turn,
+    * the MAC is idle and enough space is in slot*/ 
+   makePreamble();
+
+   if (tdma_preamble_[slot_count_] != NOTHING_TO_SEND)
+    send();
+   else 
+    radioSwitch(OFF);
 
-  slot_count_++;
+   residue_ = 0;   
+   return;
+  }
+  residue_ -= slot_packet_len_;
   return;
  }
- 
+
  // If I am supposed to listen in this slot
- if ((tdma_preamble_[slot_count_] == index_) || ((u_int32_t)tdma_preamble_[slot_count_] == MAC_BROADCAST)) {
-  //printf("<%d>, %f, preamble[%d]=%d, I am supposed to receive now.\n", index_, NOW, slot_count_, tdma_preamble_[slot_count_]);
-  slot_count_++;
+ if ((tdma_preamble_[slot_count_] == index_) || 
+  ((u_int32_t)tdma_preamble_[slot_count_] == MAC_BROADCAST)) {
 
   // Wake up the receive packets.
   radioSwitch(ON);
   return;
  }
-
+ 
  // If I dont send / recv, do nothing.
- //printf("<%d>, %f, preamble[%d]=%d, nothing to do now.\n", index_, NOW, slot_count_, tdma_preamble_[slot_count_]);
  radioSwitch(OFF);
- slot_count_++;
  return;
 }
 
 void MacTdma::recvHandler(Event *e) 
 {
+
  u_int32_t dst, src; 
  int size;
  struct hdr_cmn *ch = HDR_CMN(pktRx_);
@@ -605,20 +817,22 @@
 /* After transmission a certain packet. Turn off the radio. */
 void MacTdma::sendHandler(Event *e) 
 {
- //  printf("<%d>, %f, send a packet finished.\n", index_, NOW);
-
+ 
  /* Once transmission is complete, drop the packet. 
     p  is just for schedule a event. */
- SET_TX_STATE(MAC_IDLE);
  Packet::free((Packet *)e);
-  
- // Turn off the radio after sending the whole packet
- radioSwitch(OFF);
-
+ 
  /* unlock IFQ. */
+ SET_TX_STATE(MAC_IDLE);
+ 
  if(callback_) {
   Handler *h = callback_;
   callback_ = 0;
   h->handle((Event*) 0);
- } 
+ }
+ 
+ /* Turn off the radio after sending the whole packet */
+ radioSwitch(OFF);
 }
+
+
--- ns-allinone-2.32.bak/ns-2.32/Makefile.in 2008-04-15 17:40:01.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/Makefile.in 2008-04-15 17:43:11.000000000 +1000
@@ -232,7 +232,7 @@
  common/Decapsulator.o common/Encapsulator.o \
  common/encap.o \
  mac/channel.o mac/mac.o mac/ll.o mac/mac-802_11.o \
- mac/mac-802_3.o mac/mac-tdma.o mac/smac.o \
+ mac/mac-802_3.o mac/mac-tdma.o mac/smac.o mac/mac-bod.o \
  mobile/mip.o mobile/mip-reg.o mobile/gridkeeper.o \
  mobile/propagation.o mobile/tworayground.o \
  mobile/antenna.o mobile/omni-antenna.o \
--- ns-allinone-2.32.bak/ns-2.32/tcl/lib/ns-default.tcl 2008-04-15 17:40:05.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/tcl/lib/ns-default.tcl 2008-04-15 17:43:11.000000000 +1000
@@ -654,7 +654,9 @@
 God set debug_ false
 
 Mac/Tdma set slot_packet_len_ 1500
-Mac/Tdma set max_node_num_ 64
+Mac/Tdma set num_frame_         1
+Mac/Tdma set max_slot_num_      64
+Mac/Tdma set dump_alloc_        0
 
 LL set mindelay_                50us
 LL set delay_                   25us
--- ns-allinone-2.32.bak/ns-2.32/tcl/lib/ns-sat.tcl 2008-04-15 17:40:05.000000000 +1000
+++ ns-allinone-2.32/ns-2.32/tcl/lib/ns-sat.tcl 2008-04-15 17:43:11.000000000 +1000
@@ -689,22 +689,21 @@
  set toNode_ -1
 
  set enqT_($index_) [$ns create-trace Sat/Enque $f $fromNode_ $toNode_]
- $enqT_($index_) target $ifq_($index_)
+ $enqT_($index_) target [$ll_($index_) down-target]
  $ll_($index_) down-target $enqT_($index_)
 
  set deqT_($index_) [$ns create-trace Sat/Deque $f $fromNode_ $toNode_]
- $deqT_($index_) target $mac_($index_)
+ $deqT_($index_) target [$ifq_($index_) target]
  $ifq_($index_) target $deqT_($index_)
 
  set drpT_($index_) [$ns create-trace Sat/Drop $f $fromNode_ $toNode_]
  $drpT_($index_) target [$drophead_($index_) target]
  $drophead_($index_) target $drpT_($index_)
- $ifq_($index_) drop-target $drpT_($index_)
 }
 
 # Trace element between mac and ll tracing packets between node and node
 Node/SatNode instproc trace-inlink-queue {f {index_ 0} } {
- $self instvar id_ rcvT_ mac_ ll_ phy_rx_ em_ errT_    
+ $self instvar id_ rcvT_ mac_ ll_ phy_rx_ em_ errT_
 
  set ns [Simulator instance]
  set toNode_ $id_
@@ -725,9 +724,92 @@
   $rcvT_($index_) target [$mac_($index_) up-target]
   $mac_($index_) up-target $rcvT_($index_)
  }
- 
 }
 
+Node/SatNode instproc insert-monitor { {index_ 0}} {
+ $self instvar qMonitor_ snoopIn_ snoopOut_ snoopDrop_
+ $self instvar ll_ ifq_ drophead_ bytesInt_ pktsInt_ requester_
+
+ set snoopIn_($index_)   [new SnoopQueue/In]
+ set snoopOut_($index_)  [new SnoopQueue/Out]
+ set snoopDrop_($index_) [new SnoopQueue/Drop]
+
+ $snoopIn_($index_) target [$ll_($index_) down-target] 
+ $ll_($index_) down-target $snoopIn_($index_)
+
+ $snoopOut_($index_) target [$ifq_($index_) target]
+ $ifq_($index_) target $snoopOut_($index_)
+
+ $snoopDrop_($index_) target [$drophead_($index_) target]
+ $drophead_($index_) target $snoopDrop_($index_)
+
+ set bytesInt_($index_) [new Integrator]
+ $qMonitor_($index_) set-bytes-integrator $bytesInt_($index_)
+
+ set pktsInt_($index_) [new Integrator]
+ $qMonitor_($index_) set-pkts-integrator $pktsInt_($index_)
+
+ $requester_ set qMonitor_ $qMonitor_($index_)
+
+ $snoopIn_($index_) set-monitor $qMonitor_($index_)
+ $snoopOut_($index_) set-monitor $qMonitor_($index_)
+ $snoopDrop_($index_) set-monitor $qMonitor_($index_)
+} 
+
+
+Node/SatNode instproc install-requester { type {index_ 0} } {
+ $self instvar mac_ requester_ ifq_ qMonitor_ id_
+
+ set qMonitor_($index_) [new QueueMonitor] 
+ if {[info exist mac_($index_)]} {
+  set requester_ [new $type]
+  $requester_ attach $mac_($index_)
+  $requester_ setifq $ifq_($index_)
+  $requester_ set ifq_ $ifq_($index_)
+  $requester_ set id_ $id_
+  $requester_ set node_ $self
+  $self insert-monitor $index_
+ }
+ $requester_ setmon $qMonitor_($index_) 
+ return $requester_
+}
+
+Node/SatNode instproc install-allocator {type {index_ 0} } {
+ $self instvar mac_ allocator_
+ if {[info exist mac_($index_)]} {
+  set allocator_ [new $type]
+  $allocator_ attach $mac_($index_)
+ }
+ return $allocator_
+}
+
+Node/SatNode instproc trace-event { filedes {index_ 0}} {
+ $self instvar mac_ et_
+ if {[info exist mac_($index_)]} {
+  set et_ [new BaseTrace/Event]
+  $et_ attach $filedes
+  $mac_($index_) eventtrace $et_
+ }
+ return $et_ 
+}
+
+Allocator/Tcl instproc initvar { } { 
+ # nothing
+}
+
+Allocator/Tcl instproc allocation { } {
+ puts stderr "warning: allocation function undefined" 
+ exit
+}
+
+Requester/Tcl instproc initvar { } {
+ #nothing
+}
+
+Requester/Tcl instproc dorequest  { } { 
+ puts stderr "warning: dorequest function undefined"
+ exit
+}
 
 ###########
 # TRACE MODIFICATIONS
@@ -804,3 +886,15 @@
 Agent/SatRoute set myaddr_       0        ;# My address
 Mac/Sat set bandwidth_ 2Mb 
 
+Allocator/Proportional set delay_ 1.6
+Allocator/Proportional set active_node_ 0
+Allocator/Proportional set max_slot_num_ 64
+
+Allocator/Tcl set delay_ 1.6
+Allocator/Tcl set active_node_ 0
+Allocator/Tcl set max_slot_num_ 64
+
+Requester/Constant set request_ 1;
+Requester/RBDC set request_ 1;
+Requester/VBDC set request_ 1;
+Requester/Tcl set request_ 1;


0 comments:

Post a Comment