00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef lint
00054 static const char rcsid[] =
00055 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/realaudio/realaudio.cc,v 1.6 2005/08/25 18:58:11 johnh Exp $ (USC/ISI)";
00056 #endif
00057
00058 #ifndef WIN32
00059 #include <sys/time.h>
00060 #endif
00061 #include "random.h"
00062 #include "trafgen.h"
00063 #include "ranvar.h"
00064
00065 class RA_Traffic : public TrafficGenerator {
00066 public:
00067 RA_Traffic();
00068 int loadCDF(const char* filename);
00069 int lookup(double u);
00070 virtual double value();
00071 virtual double interpolate(double u, double x1, double y1, double x2, double y2);
00072 virtual double next_interval(int&);
00073
00074 protected:
00075 void init();
00076 double ontime_;
00077 double offtime_;
00078 double rate_;
00079 double interval_;
00080 double burstlen_;
00081 unsigned int rem_;
00082 double minCDF_;
00083 double maxCDF_;
00084 int interpolation_;
00085 int numEntry_;
00086 int maxEntry_;
00087 CDFentry* table_;
00088 RNG* rng_;
00089
00090
00091
00092 };
00093
00094
00095 static class RATrafficClass : public TclClass {
00096 public:
00097 RATrafficClass() : TclClass("Application/Traffic/RealAudio") {}
00098 TclObject* create(int, const char*const*) {
00099 return (new RA_Traffic());
00100 }
00101 } class_ra_traffic;
00102
00103 RA_Traffic::RA_Traffic() : minCDF_(0), maxCDF_(1), maxEntry_(32), table_(0)
00104 {
00105 bind("minCDF_", &minCDF_);
00106 bind("maxCDF_", &maxCDF_);
00107 bind("interpolation_", &interpolation_);
00108 bind("maxEntry_", &maxEntry_);
00109 bind_time("burst_time_", &ontime_);
00110 bind_time("idle_time_", &offtime_);
00111 bind_bw("rate_", &rate_);
00112 bind("packetSize_", &size_);
00113
00114 rng_ = RNG::defaultrng();
00115 }
00116
00117 void RA_Traffic::init()
00118 {
00119 int res = loadCDF("offtimecdf");
00120
00121 timeval tv;
00122 gettimeofday(&tv, 0);
00123
00124 if (res < 0) printf("error:unable to load offtimecdf");
00125
00126 interval_ = ontime_ ;
00127 burstlen_ = (double) ( rate_ * (ontime_ + offtime_))/ (double)(size_ << 3);
00128 rem_ = 0;
00129 if (agent_)
00130 agent_->set_pkttype(PT_REALAUDIO);
00131 }
00132
00133 double RA_Traffic::next_interval(int& size)
00134 {
00135
00136 double o = value() ;
00137
00138 double t = ontime_ ;
00139
00140
00141
00142
00143 if (rem_ == 0) {
00144
00145 rem_ = int(burstlen_ + .5);
00146
00147
00148
00149 if (o > offtime_ ) {
00150 double b =
00151
00152 (double) ( rate_ * (t + o))/ (double)(size_ << 3);
00153 rem_ = int(b);
00154 }
00155
00156
00157
00158
00159
00160 if (rem_<= 0)
00161 rem_ = 1;
00162
00163 t += o ;
00164 }
00165 rem_--;
00166
00167 size = size_;
00168 return(t);
00169
00170 }
00171
00172 int RA_Traffic::loadCDF(const char* filename)
00173 {
00174 FILE* fp;
00175 char line[256];
00176 CDFentry* e;
00177
00178 fp = fopen(filename, "r");
00179 if (fp == 0)
00180 return 0;
00181
00182 if (table_ == 0)
00183 table_ = new CDFentry[maxEntry_];
00184 for (numEntry_=0; fgets(line, 256, fp); numEntry_++) {
00185 if (numEntry_ >= maxEntry_) {
00186 maxEntry_ *= 2;
00187 e = new CDFentry[maxEntry_];
00188 for (int i=numEntry_-1; i >= 0; i--)
00189 e[i] = table_[i];
00190 delete table_;
00191 table_ = e;
00192 }
00193 e = &table_[numEntry_];
00194
00195 sscanf(line, "%lf %*f %lf", &e->val_, &e->cdf_);
00196 }
00197 return numEntry_;
00198 }
00199
00200 double RA_Traffic::value()
00201 {
00202 if (numEntry_ <= 0)
00203 return 0;
00204 double u = rng_->uniform(minCDF_, maxCDF_);
00205 int mid = lookup(u);
00206 if (mid && interpolation_ && u < table_[mid].cdf_)
00207 return interpolate(u, table_[mid-1].cdf_, table_[mid-1].val_,
00208 table_[mid].cdf_, table_[mid].val_);
00209 return table_[mid].val_;
00210 }
00211
00212 double RA_Traffic::interpolate(double x, double x1, double y1, double x2, double y2)
00213 {
00214 double value = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
00215 if (interpolation_ == INTER_INTEGRAL)
00216 return ceil(value);
00217 return value;
00218 }
00219
00220 int RA_Traffic::lookup(double u)
00221 {
00222
00223 int lo, hi, mid;
00224 if (u <= table_[0].cdf_)
00225 return 0;
00226 for (lo=1, hi=numEntry_-1; lo < hi; ) {
00227 mid = (lo + hi) / 2;
00228 if (u > table_[mid].cdf_)
00229 lo = mid + 1;
00230 else hi = mid;
00231 }
00232 return lo;
00233 }