Reworked a little, and added functionality to rcmacgw
authorltracy
Fri May 01 00:35:34 2009 -0700 (9 months ago)
changeset 445290468ce0c82e
parent 4451 737145998f3c
child 4453 ff5c0bdb7a1e
Reworked a little, and added functionality to rcmacgw
scratch/rctest.cc
src/devices/uan/uan-mac-rc-gw.cc
src/devices/uan/uan-mac-rc-gw.h
     1.1 --- a/scratch/rctest.cc	Tue Apr 28 13:06:24 2009 -0700
     1.2 +++ b/scratch/rctest.cc	Fri May 01 00:35:34 2009 -0700
     1.3 @@ -137,6 +137,9 @@
     1.4    uint32_t pktSize = 1000;
     1.5    std::string tputfile = "rctest.dat";
     1.6    std::string cycleFile = "cycles.dat";
     1.7 +  bool doNode = true;
     1.8 +  uint32_t nmin = 5;
     1.9 +  uint32_t nmax = 30;
    1.10  
    1.11    CommandLine cmd;
    1.12    cmd.AddValue("RunNumber", "RunNumber to give to RNG", runNumber);
    1.13 @@ -178,7 +181,15 @@
    1.14        SeedManager::SetRun(runNumber);
    1.15      }
    1.16  
    1.17 -  for(uint32_t km=amin;km<=amax;km++)
    1.18 +  uint32_t simMin = amin;
    1.19 +  uint32_t simMax = amax;
    1.20 +
    1.21 +  if(doNode)
    1.22 +    {
    1.23 +      simMin = nmin;
    1.24 +      simMax = nmax;
    1.25 +    }
    1.26 +  for(uint32_t km=simMin;km<=simMax;km++)
    1.27      {
    1.28  
    1.29  
    1.30 @@ -187,13 +198,29 @@
    1.31  
    1.32        Time pDelay = Seconds(sqrt(2.0)*maxr/3000.0);
    1.33  
    1.34 -      uan.SetMac("ns3::UanMacRcGw",
    1.35 -          "NumberOfRates", UintegerValue(dataModes.GetNModes()),
    1.36 -          "NumberOfNodes", UintegerValue(N),
    1.37 -          "MaxReservations", UintegerValue(km),
    1.38 -          "RetryRate", DoubleValue(1/30.0),
    1.39 -          "SIFS", TimeValue(Seconds(SIFS)),
    1.40 -          "MaxPropDelay", TimeValue(pDelay));
    1.41 +      if(doNode)
    1.42 +        {
    1.43 +          N = km;
    1.44 +          uan.SetMac("ns3::UanMacRcGw",
    1.45 +              "NumberOfRates", UintegerValue(dataModes.GetNModes()),
    1.46 +              "NumberOfNodes", UintegerValue(km),
    1.47 +              "MaxReservations", UintegerValue(0),
    1.48 +              "RetryRate", DoubleValue(1/30.0),
    1.49 +              "SIFS", TimeValue(Seconds(SIFS)),
    1.50 +              "MaxPropDelay", TimeValue(pDelay),
    1.51 +              "FrameSize", UintegerValue(pktSize));
    1.52 +        }
    1.53 +      else
    1.54 +        {
    1.55 +          uan.SetMac("ns3::UanMacRcGw",
    1.56 +              "NumberOfRates", UintegerValue(dataModes.GetNModes()),
    1.57 +              "NumberOfNodes", UintegerValue(N),
    1.58 +              "MaxReservations", UintegerValue(km),
    1.59 +              "RetryRate", DoubleValue(1/30.0),
    1.60 +              "SIFS", TimeValue(Seconds(SIFS)),
    1.61 +              "MaxPropDelay", TimeValue(pDelay),
    1.62 +              "FrameSize", UintegerValue(pktSize));
    1.63 +        }
    1.64  
    1.65  
    1.66        Ptr<UanChannel> chan = CreateObject<UanChannel>();
    1.67 @@ -216,7 +243,9 @@
    1.68        uan.SetMac("ns3::UanMacRc", "NumberOfRates", UintegerValue(dataModes.GetNModes()),
    1.69            "RetryRate", DoubleValue(1/100.0), "MaxPropDelay", TimeValue(pDelay));
    1.70  
    1.71 +
    1.72        NodeContainer nodes;
    1.73 +
    1.74        nodes.Create(N);
    1.75  
    1.76        NetDeviceContainer devices = uan.Install(nodes, chan);
    1.77 @@ -294,7 +323,10 @@
    1.78        std::cout << "Received " << m_bytesRx << " bytes at sink" << std::endl;
    1.79        std::cout << "Control channel attempts " << m_cntrlSends << std::endl;
    1.80        double throughput = m_bytesRx*8.0/(5000.0*totalRate);
    1.81 -      std::cout << "a = " << km << "   Throughput = " << throughput << std::endl;
    1.82 +      if(!doNode)
    1.83 +        std::cout << "a = " << km << "   Throughput = " << throughput << std::endl;
    1.84 +      else
    1.85 +        std::cout << "N = " << N << "   Throughput = " << throughput << std::endl;
    1.86  
    1.87        data << km << " " << throughput << std::endl;
    1.88        m_bytesRx = 0;
     2.1 --- a/src/devices/uan/uan-mac-rc-gw.cc	Tue Apr 28 13:06:24 2009 -0700
     2.2 +++ b/src/devices/uan/uan-mac-rc-gw.cc	Fri May 01 00:35:34 2009 -0700
     2.3 @@ -38,6 +38,8 @@
     2.4  #include <utility>
     2.5  #include <set>
     2.6  #include <map>
     2.7 +#include <vector>
     2.8 +#include <algorithm>
     2.9  
    2.10  NS_LOG_COMPONENT_DEFINE("UanMacRcGw");
    2.11  
    2.12 @@ -53,7 +55,7 @@
    2.13  }
    2.14  
    2.15  
    2.16 -UanMacRcGw::UanMacRcGw() :
    2.17 +UanMacRcGw::UanMacRcGw () :
    2.18    m_state(IDLE),
    2.19    m_currentRateNum(0)
    2.20  {
    2.21 @@ -71,13 +73,13 @@
    2.22    NS_LOG_DEBUG("Gateway initialized");
    2.23  }
    2.24  
    2.25 -UanMacRcGw::~UanMacRcGw()
    2.26 +UanMacRcGw::~UanMacRcGw ()
    2.27  {
    2.28    // TODO Auto-generated destructor stub
    2.29  }
    2.30  
    2.31  TypeId
    2.32 -UanMacRcGw::GetTypeId(void)
    2.33 +UanMacRcGw::GetTypeId (void)
    2.34  {
    2.35    TypeId tid = TypeId("ns3::UanMacRcGw")
    2.36        .SetParent<UanMac>()
    2.37 @@ -137,6 +139,11 @@
    2.38                      UintegerValue(4),
    2.39                      MakeUintegerAccessor(&UanMacRcGw::m_rateStep),
    2.40                      MakeUintegerChecker<uint32_t>())
    2.41 +      .AddAttribute("FrameSize",
    2.42 +                    "Size of data frames in bytes",
    2.43 +                    UintegerValue(1000),
    2.44 +                    MakeUintegerAccessor(&UanMacRcGw::m_frameSize),
    2.45 +                    MakeUintegerChecker<uint32_t>())
    2.46  
    2.47  //      .AddTraceSource("Enqueue",
    2.48  //                    "A (data) packet arrived at MAC for transmission",
    2.49 @@ -157,33 +164,33 @@
    2.50  }
    2.51  
    2.52  Address
    2.53 -UanMacRcGw::GetAddress(void)
    2.54 +UanMacRcGw::GetAddress (void)
    2.55  {
    2.56    return m_address;
    2.57  }
    2.58  
    2.59  void
    2.60 -UanMacRcGw::SetAddress(UanAddress addr)
    2.61 +UanMacRcGw::SetAddress (UanAddress addr)
    2.62  {
    2.63    m_address = addr;
    2.64  }
    2.65  
    2.66  bool
    2.67 -UanMacRcGw::Enqueue(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
    2.68 +UanMacRcGw::Enqueue (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
    2.69  {
    2.70    NS_LOG_WARN("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
    2.71    return false;
    2.72  }
    2.73  
    2.74  void
    2.75 -UanMacRcGw::SetForwardUpCb(Callback<void, Ptr<Packet>, const UanAddress&> cb)
    2.76 +UanMacRcGw::SetForwardUpCb (Callback<void, Ptr<Packet>, const UanAddress&> cb)
    2.77  {
    2.78    //NS_LOG_WARN("RCMAC Gateway transmission to acoustic nodes is not yet implemented");
    2.79    m_forwardUpCb = cb;
    2.80  }
    2.81  
    2.82  void
    2.83 -UanMacRcGw::AttachPhy(Ptr<UanPhy> phy)
    2.84 +UanMacRcGw::AttachPhy (Ptr<UanPhy> phy)
    2.85  {
    2.86    m_phy = phy;
    2.87    phy->SetReceiveOkCallback(MakeCallback(&UanMacRcGw::ReceivePacket, this));
    2.88 @@ -191,7 +198,7 @@
    2.89  }
    2.90  
    2.91  void
    2.92 -UanMacRcGw::ReceiveError(Ptr<Packet> pkt, double sinr)
    2.93 +UanMacRcGw::ReceiveError (Ptr<Packet> pkt, double sinr)
    2.94  {
    2.95  //  std::string type;
    2.96  //  UanHeaderCommon ch;
    2.97 @@ -220,13 +227,13 @@
    2.98  //  NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Received in error: Packet of type " << type << " from " << ch.GetSrc() << " with SINR " << sinr << " and mode ?");
    2.99  }
   2.100  Address
   2.101 -UanMacRcGw::GetBroadcast(void) const
   2.102 +UanMacRcGw::GetBroadcast (void) const
   2.103  {
   2.104    return UanAddress::GetBroadcast();
   2.105  }
   2.106  
   2.107  void
   2.108 -UanMacRcGw::ReceivePacket(Ptr<Packet> pkt, double sinr, UanTxMode mode)
   2.109 +UanMacRcGw::ReceivePacket (Ptr<Packet> pkt, double sinr, UanTxMode mode)
   2.110  {
   2.111    UanHeaderCommon ch;
   2.112    pkt->PeekHeader(ch);
   2.113 @@ -308,7 +315,7 @@
   2.114  }
   2.115  
   2.116  void
   2.117 -UanMacRcGw::StartCycle(void)
   2.118 +UanMacRcGw::StartCycle (void)
   2.119  {
   2.120  
   2.121  
   2.122 @@ -337,32 +344,39 @@
   2.123  
   2.124    double minRate = m_phy->GetMode(m_numRates).GetDataRateBps();
   2.125  
   2.126 -  //Temp values
   2.127 -  // double beta = numRts*m_sifs.GetSeconds() + pDelay - 2*m_maxDelta.GetSeconds();
   2.128 -  double aelr = 16.0*m_rtsSize * m_maxRes * exp(1.0);
   2.129 -  double st = totalFrames * m_sifs.GetSeconds() * m_totalRate;
   2.130 -  double pt = (2.0*m_maxDelta.GetSeconds() - pDelay) * m_totalRate;
   2.131 -  double aa = pt - st ;
   2.132 -  double bb = 8.0*totalBytes - pt + 8.0*m_rtsSize + st + aelr ;
   2.133 -  double cc = -8.0*m_rtsSize - aelr;
   2.134 -  double thAlpha;
   2.135 -  if(numRts > 0)
   2.136 +//  //Temp values
   2.137 +//  // double beta = numRts*m_sifs.GetSeconds() + pDelay - 2*m_maxDelta.GetSeconds();
   2.138 +//  double aelr = 16.0*m_rtsSize * m_maxRes * exp(1.0);
   2.139 +//  double st = totalFrames * m_sifs.GetSeconds() * m_totalRate;
   2.140 +//  double pt = (2.0*m_maxDelta.GetSeconds() - pDelay) * m_totalRate;
   2.141 +//  double aa = pt - st ;
   2.142 +//  double bb = 8.0*totalBytes - pt + 8.0*m_rtsSize + st + aelr ;
   2.143 +//  double cc = -8.0*m_rtsSize - aelr;
   2.144 +//  double thAlpha;
   2.145 +//  if(numRts > 0)
   2.146 +//    {
   2.147 +//      if(-cc/aa > 0)
   2.148 +//	{
   2.149 +//	  thAlpha = -bb/(2*aa) + sqrt(bb*bb/ (4*aa*aa) - cc/aa);
   2.150 +//	}
   2.151 +//      else
   2.152 +//	{
   2.153 +//	  thAlpha = -bb/(2*aa) - sqrt(bb*bb/ (4*aa*aa) - cc/aa);
   2.154 +//	}
   2.155 +//    }
   2.156 +//  else
   2.157 +//    {
   2.158 +//      thAlpha = (16.0 * m_rtsSize*m_maxRes*exp(1.0) + 8.0*m_rtsSize - sqrt(m_ctsSizeG * m_rtsSize*64.0 + 128.0*m_ctsSizeG*m_rtsSize*m_maxRes*exp(1.0)) ) / ( 16.0 * m_rtsSize * m_maxRes * exp(1.0) + 8.0*m_rtsSize - 8.0*m_ctsSizeG);
   2.159 +//    }
   2.160 +//  NS_ASSERT( 0.00 <= thAlpha);
   2.161 +//  NS_ASSERT( thAlpha <= 1.0);
   2.162 +
   2.163 +  uint32_t optA = m_maxRes;
   2.164 +  if(m_maxRes == 0)
   2.165      {
   2.166 -      if(-cc/aa > 0)
   2.167 -	{
   2.168 -	  thAlpha = -bb/(2*aa) + sqrt(bb*bb/ (4*aa*aa) - cc/aa);
   2.169 -	}
   2.170 -      else
   2.171 -	{
   2.172 -	  thAlpha = -bb/(2*aa) - sqrt(bb*bb/ (4*aa*aa) - cc/aa);
   2.173 -	}
   2.174 +      optA = FindOptA();
   2.175      }
   2.176 -  else
   2.177 -    {
   2.178 -      thAlpha = (16.0 * m_rtsSize*m_maxRes*exp(1.0) + 8.0*m_rtsSize - sqrt(m_ctsSizeG * m_rtsSize*64.0 + 128.0*m_ctsSizeG*m_rtsSize*m_maxRes*exp(1.0)) ) / ( 16.0 * m_rtsSize * m_maxRes * exp(1.0) + 8.0*m_rtsSize - 8.0*m_ctsSizeG);
   2.179 -    }
   2.180 -  NS_ASSERT( 0.00 <= thAlpha);
   2.181 -  NS_ASSERT( thAlpha <= 1.0);
   2.182 +  double thAlpha = ComputeAlpha(totalFrames, totalBytes, m_numNodes, optA, pDelay/2.0);
   2.183  
   2.184    double thCtlRate = m_totalRate*thAlpha;
   2.185  
   2.186 @@ -397,13 +411,11 @@
   2.187    double winSize = (double) (totalBytes)*8.0/dataRate + m_sifs.GetSeconds()*totalFrames + pDelay;
   2.188    if(numRts == 0)
   2.189      {
   2.190 -      winSize = (m_maxRes * exp(1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2*m_maxDelta.GetSeconds();
   2.191 +      winSize = (optA * exp(1.0) + 0.5) * 2.0 * 8.0 * m_rtsSize / (thAlpha * m_totalRate) + 2*m_maxDelta.GetSeconds();
   2.192      }
   2.193    double effWinSize = winSize - m_rtsSize*8/ctlRate  - 2 * m_maxDelta.GetSeconds();
   2.194  
   2.195  
   2.196 -
   2.197 -
   2.198    //Before fast CTS/ACK(below)
   2.199    double cycleSeconds = winSize + (totalFrames + 1.0) * m_sifs.GetSeconds() + m_ctsSizeG*8.0/dataRate + (m_ctsSizeN + m_ackSize)*8.0*numRts/dataRate;
   2.200    //fast CTS/ACK (below)
   2.201 @@ -500,12 +512,12 @@
   2.202  }
   2.203  
   2.204  void
   2.205 -UanMacRcGw::CycleStarted()
   2.206 +UanMacRcGw::CycleStarted ()
   2.207  {
   2.208    m_state = INCYCLE;
   2.209  }
   2.210  void
   2.211 -UanMacRcGw::EndCycle()
   2.212 +UanMacRcGw::EndCycle ()
   2.213  {
   2.214  
   2.215    NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW Ending cycle");
   2.216 @@ -549,7 +561,7 @@
   2.217  
   2.218  }
   2.219  void
   2.220 -UanMacRcGw::SendPacket(Ptr<Packet> pkt, uint32_t rate)
   2.221 +UanMacRcGw::SendPacket (Ptr<Packet> pkt, uint32_t rate)
   2.222  {
   2.223    UanHeaderCommon ch;
   2.224    pkt->PeekHeader(ch);
   2.225 @@ -579,4 +591,185 @@
   2.226    m_phy->SendPacket(pkt, rate);
   2.227  }
   2.228  
   2.229 +
   2.230 +double
   2.231 +UanMacRcGw::ComputeAlpha (uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK)
   2.232 +{
   2.233 +  //NS_LOG_DEBUG("Computing alpha for: " << totalFrames << " frames " << totalBytes << " bytes " << n << " nodes " << a << " maxrea " << deltaK << " prop. delay term");
   2.234 +
   2.235 +  double alpha;
   2.236 +  double lrae = m_rtsSize*8.0*a*std::exp(1.0);
   2.237 +  if(totalFrames==0)
   2.238 +    {
   2.239 +
   2.240 +      alpha =  (2.0*lrae + 8.0*m_rtsSize - std::sqrt(m_ctsSizeG*8.0*8.0*m_rtsSize + 2 * 8.0*m_ctsSizeG*8.0*m_rtsSize*a*std::exp(1.0)) )/
   2.241 +               (2*lrae + 8.0*m_rtsSize - 8.0*m_ctsSizeG);
   2.242 +    }
   2.243 +  else
   2.244 +    {
   2.245 +      double w = totalBytes*8.0 + totalFrames*m_sifs.GetSeconds()*m_totalRate;
   2.246 +      double v = m_rtsSize*8.0 + 2*lrae;
   2.247 +      double u = (2*m_maxDelta.GetSeconds() - 2*deltaK)*m_totalRate;
   2.248 +
   2.249 +      double gamma = (w - u + v) / (2 * (u - totalFrames*m_sifs.GetSeconds()*m_totalRate));
   2.250 +
   2.251 +      alpha = -gamma + sqrt(gamma*gamma + v / (u - totalFrames*m_sifs.GetSeconds()*m_totalRate));
   2.252 +      //NS_LOG_DEBUG("aa = " << u - totalFrames*m_sifs.GetSeconds()*m_totalRate << " bb = " << w - u + v << " cc = " << v);
   2.253 +
   2.254 +      if(alpha < 0 || alpha > 1)
   2.255 +        {
   2.256 +          //NS_LOG_DEBUG("Not liking: " << alpha);
   2.257 +          alpha = -gamma - sqrt(gamma*gamma + v / (u - totalFrames*m_sifs.GetSeconds()*m_totalRate));
   2.258 +
   2.259 +        }
   2.260 +
   2.261 +    }
   2.262 +  //NS_LOG_DEBUG("Computed alpha " << alpha);
   2.263 +  NS_ASSERT_MSG(alpha > 0 && alpha < 1, "Error computing alpha.  Alpha out of valid range!");
   2.264 +  return alpha;
   2.265 +}
   2.266 +
   2.267 +std::vector<double>
   2.268 +UanMacRcGw::GetExpPdk (void)
   2.269 +{
   2.270 +  uint32_t n = m_numNodes;
   2.271 +  std::vector<double> pds;
   2.272 +  std::map<UanAddress, Time>::iterator pdit = m_propDelay.begin();
   2.273 +
   2.274 +  for(;pdit != m_propDelay.end();pdit++)
   2.275 +    {
   2.276 +      pds.push_back(pdit->second.GetSeconds());
   2.277 +    }
   2.278 +  while(pds.size() < m_numNodes)
   2.279 +    {
   2.280 +      pds.push_back(m_maxDelta.GetSeconds());
   2.281 +    }
   2.282 +
   2.283 +  std::sort(pds.begin(), pds.end());
   2.284 +  //Find expected min. prop. delay for k nodes
   2.285 +  std::vector<double> exppdk;
   2.286 +  exppdk.push_back(m_maxDelta.GetSeconds());
   2.287 +  for(uint32_t k=1;k<=n;k++)
   2.288 +    {
   2.289 +      uint32_t ind = CompExpMinIndex(n,k)-1;
   2.290 +//      NS_LOG_DEBUG("Exp. min. index for k=" << k << " = " << ind << " => pds[ind]=" << pds[ind]);
   2.291 +      exppdk.push_back(pds[ind]);
   2.292 +    }
   2.293 +  return exppdk;
   2.294 +}
   2.295 +
   2.296 +double
   2.297 +UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld, std::vector<double> exppdk)
   2.298 +{
   2.299 +  UanHeaderCommon ch;
   2.300 +  uint32_t lh = ch.GetSerializedSize();
   2.301 +
   2.302 +  uint32_t n = m_numNodes;
   2.303 +  double expk = n*(1 - std::exp(-((double) a) / (double) n));
   2.304 +  NS_LOG_DEBUG("expk = " << expk);
   2.305 +
   2.306 +  //Compute expected data per cycle
   2.307 +  double expdata = 8*ld*expk;
   2.308 +
   2.309 +  //Compute expected time per cycle
   2.310 +  double alpha0 = ComputeAlpha(0,0,n,a,exppdk[0]);
   2.311 +  double c0 = 8.0*m_ctsSizeG / ( m_totalRate * (1 - alpha0)) + 2*m_maxDelta.GetSeconds() + (a * std::exp(1.0) + 0.5)*2*m_rtsSize*8.0 / (alpha0*m_totalRate);
   2.312 +  double exptime = ComputePiK(a,n,0) * c0;
   2.313 +  double expp = 0;
   2.314 +  for(uint32_t i=1;i<=n;i++)
   2.315 +    {
   2.316 +      expp += ComputePiK(a,n,i) * exppdk[i-1];
   2.317 +    }
   2.318 +
   2.319 +  //NS_LOG_DEBUG("Found expp=" << expp);
   2.320 +  exptime += ComputeExpBOverA(n,a,ld+lh,exppdk) + expk*2*m_sifs.GetSeconds() + m_sifs.GetSeconds() + 2*expp;
   2.321 +  double s =(1.0 / m_totalRate) * expdata/exptime;
   2.322 +  //NS_LOG_DEBUG("For a = " << a << " and ld = " << ld << " Found tput=" << s << " from expdata=" << expdata << " and exptime=" << exptime);
   2.323 +  return s;
   2.324 +}
   2.325 +
   2.326 +double
   2.327 +UanMacRcGw::ComputeExpS (uint32_t a, uint32_t ld)
   2.328 +{
   2.329 +  return ComputeExpS(a, ld, GetExpPdk());
   2.330 +}
   2.331 +
   2.332 +uint32_t
   2.333 +UanMacRcGw::CompExpMinIndex (uint32_t n, uint32_t k)
   2.334 +{
   2.335 +  double sum=0;
   2.336 +  for(uint32_t i=1;i<=n-k+1;i++)
   2.337 +    {
   2.338 +      double p = (double) NchooseK(n-i, k-1) / NchooseK(n, k);
   2.339 +      sum += p*i;
   2.340 +    }
   2.341 +  return (uint32_t) (sum + 0.5);
   2.342 +}
   2.343 +
   2.344 +double
   2.345 +UanMacRcGw::ComputePiK (uint32_t a, uint32_t n, uint32_t k)
   2.346 +{
   2.347 +  double nck = (double) NchooseK(n, k);
   2.348 +  return nck*std::pow((std::exp((double) a / (double) n) - 1.0), (double) k)*std::exp(-( (double) a));
   2.349 +}
   2.350 +
   2.351 +double
   2.352 +UanMacRcGw::ComputeExpBOverA (uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK)
   2.353 +{
   2.354 +
   2.355 +  double sum=0;
   2.356 +  uint32_t lt = 8.0*(m_ctsSizeN + ldlh + m_ackSize);
   2.357 +  for(uint32_t k=1; k<= n; k++)
   2.358 +    {
   2.359 +      double num = 8.0*m_ctsSizeG + k*lt;
   2.360 +      double denom = (1.0 - ComputeAlpha(k, k*ldlh, n, a, deltaK[k]))*m_totalRate;
   2.361 +      double pik = ComputePiK(a, n, k);
   2.362 +      double term = pik*num/denom;
   2.363 +//      NS_LOG_DEBUG("Value for " << k*ldlh << " Bytes and " << k << " res. = " << pik << " * " << num << "/" << denom << " = " << term << " (SUM = " << sum << ")");
   2.364 +      sum += term;
   2.365 +    }
   2.366 +//  NS_LOG_DEBUG("Found first term of E[C(K)] = " << sum);
   2.367 +  return sum;
   2.368 +}
   2.369 +
   2.370 +uint64_t
   2.371 +UanMacRcGw::NchooseK (uint32_t n, uint32_t k)
   2.372 +{
   2.373 +  if (k > n)
   2.374 +      return 0;
   2.375 +
   2.376 +  if (k > n/2)
   2.377 +      k = n-k;
   2.378 +
   2.379 +  double accum = 1;
   2.380 +  for (uint32_t i = 1; i <= k; i++)
   2.381 +       accum = accum * (n-k+i) / i;
   2.382 +
   2.383 +  return (uint64_t) (accum + 0.5);
   2.384 +
   2.385 +}
   2.386 +
   2.387 +uint32_t
   2.388 +UanMacRcGw::FindOptA (void)
   2.389 +{
   2.390 +  double tput = 0;
   2.391 +  uint32_t a=1;
   2.392 +  while(1)
   2.393 +    {
   2.394 +
   2.395 +      double newtput = ComputeExpS(a, m_frameSize);
   2.396 +      if(newtput < tput)
   2.397 +        {
   2.398 +          a--;
   2.399 +          break;
   2.400 +        }
   2.401 +      else
   2.402 +        {
   2.403 +          tput = newtput;
   2.404 +          a++;
   2.405 +        }
   2.406 +    }
   2.407 +  NS_LOG_DEBUG(Simulator::Now().GetSeconds() << " GW: Found optimum a = " << a);
   2.408 +  return a;
   2.409 +}
   2.410  }// namespace ns3
     3.1 --- a/src/devices/uan/uan-mac-rc-gw.h	Tue Apr 28 13:06:24 2009 -0700
     3.2 +++ b/src/devices/uan/uan-mac-rc-gw.h	Fri May 01 00:35:34 2009 -0700
     3.3 @@ -98,6 +98,7 @@
     3.4    uint32_t m_numNodes;
     3.5    uint32_t m_totalRate;
     3.6    uint32_t m_rateStep;
     3.7 +  uint32_t m_frameSize;
     3.8  
     3.9    uint16_t m_numRetryRates;
    3.10    double m_minRetryRate;
    3.11 @@ -124,6 +125,23 @@
    3.12    void SendPacket (Ptr<Packet> pkt, uint32_t rate);
    3.13    void CycleStarted (void);
    3.14    void ReceiveError (Ptr<Packet> pkt, double sinr);
    3.15 +
    3.16 +  //Stuff for computing exp throughput
    3.17 +  double ComputeAlpha(uint32_t totalFrames, uint32_t totalBytes, uint32_t n, uint32_t a, double deltaK);
    3.18 +  std::vector<double>  GetExpPdk(void);
    3.19 +  double ComputeExpS(uint32_t a, uint32_t ld, std::vector<double> exppdk);
    3.20 +  double ComputeExpS(uint32_t a, uint32_t ld);
    3.21 +  uint32_t CompExpMinIndex(uint32_t n, uint32_t k);
    3.22 +  double ComputePiK(uint32_t a, uint32_t n, uint32_t k);
    3.23 +  double ComputeExpBOverA(uint32_t n, uint32_t a, uint32_t ldlh, std::vector<double> deltaK);
    3.24 +  uint64_t NchooseK(uint32_t n, uint32_t k);
    3.25 +  uint32_t FindOptA(void);
    3.26 +
    3.27 +
    3.28 +
    3.29 +
    3.30 +
    3.31 +
    3.32  };
    3.33  
    3.34  /**