mac-csma.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Daedalus Research
  17.  * Group at the University of California Berkeley.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  * Contributed by Giao Nguyen, http://daedalus.cs.berkeley.edu/~gnguyen
  35.  */
  36. #ifndef lint
  37. static const char rcsid[] =
  38.     "@(#) $Header: /cvsroot/nsnam/ns-2/mac/mac-csma.cc,v 1.26 1998/11/17 23:36:35 yuriy Exp $ (UCB)";
  39. #endif
  40. #include "template.h"
  41. #include "random.h"
  42. #include "channel.h"
  43. #include "mac-csma.h"
  44. static class MacCsmaClass : public TclClass {
  45. public:
  46. MacCsmaClass() : TclClass("Mac/Csma") {}
  47. TclObject* create(int, const char*const*) {
  48. return (new MacCsma);
  49. }
  50. } class_mac_csma;
  51. static class MacCsmaCdClass : public TclClass {
  52. public:
  53. MacCsmaCdClass() : TclClass("Mac/Csma/Cd") {}
  54. TclObject* create(int, const char*const*) {
  55. return (new MacCsmaCd);
  56. }
  57. } class_mac_csma_cd;
  58. static class MacCsmaCaClass : public TclClass {
  59. public:
  60. MacCsmaCaClass() : TclClass("Mac/Csma/Ca") {}
  61. TclObject* create(int, const char*const*) {
  62. return (new MacCsmaCa);
  63. }
  64. } class_mac_csma_ca;
  65. void
  66. MacHandlerEoc::handle(Event* e)
  67. {
  68. mac_->endofContention((Packet*)e);
  69. }
  70. MacCsma::MacCsma() : txstart_(0), rtx_(0), csense_(1), hEoc_(this)
  71. {
  72. bind_time("ifs_", &ifs_);
  73. bind_time("slotTime_", &slotTime_);
  74. bind("cwmin_", &cwmin_);
  75. bind("cwmax_", &cwmax_);
  76. bind("rtxLimit_", &rtxLimit_);
  77. bind("csense_", &csense_);
  78. cw_ = cwmin_;
  79. }
  80. void MacCsma::resume(Packet* p)
  81. {
  82. Scheduler& s = Scheduler::instance();
  83. s.schedule(callback_, &intr_, ifs_ + slotTime_ * cwmin_);
  84. if (p != 0)
  85. drop(p);
  86. callback_ = 0;
  87. state(MAC_IDLE);
  88. rtx_ = 0;
  89. cw_ = cwmin_;
  90. }
  91. void MacCsma::send(Packet* p)
  92. {
  93. Scheduler& s = Scheduler::instance();
  94. double delay = channel_->txstop() + ifs_ - s.clock();
  95. // if channel is not ready, then wait
  96. // else content for the channel
  97. /* XXX floating point operations differences have been
  98.    observed on the resulting delay value on Pentium II and
  99.    SunSparc.  E.g.
  100.                            PentiumII                   SunSparc
  101.                            -------------------------------
  102.    channel_->txstop_=      0.11665366666666668         0.11665366666666668
  103.                    binary    0x3fbddd03c34ab4a2          0x3fbddd03c34ab4a2
  104.    ifs_=                   5.1999999999999997e-05      5.1999999999999997e-05
  105.                    binary    0x3f0b43526527a205          0x3f0b43526527a205
  106.    s.clock_=               0.11670566666666668         0.11670566666666668
  107.                    binary    0x3fbde06c2d975996          0x3fbde06c2d975996
  108.    delay=                  3.5033282698437862e-18      0
  109.                    binary    0x3c50280000000000          0x0000000000000000
  110.    Because of that the value of (csense_ && delay > 0) was different.  Fixed by
  111.    changing 0 to EPS
  112.  */
  113. static const double EPS= 1.0e-12; //seems appropriate (less than nanosec)
  114.    if (csense_ && delay > EPS)
  115. s.schedule(&hSend_, p, delay + 0.000001);
  116. else {
  117. txstart_ = s.clock();
  118. channel_->contention(p, &hEoc_);
  119. }
  120. }
  121. void MacCsma::backoff(Handler* h, Packet* p, double delay)
  122. {
  123. Scheduler& s = Scheduler::instance();
  124. double now = s.clock();
  125. // if retransmission time within limit, do exponential backoff
  126. // else drop the packet and resume
  127. if (++rtx_ < rtxLimit_) {
  128. delay += max(channel_->txstop() + ifs_ - now, 0.0);
  129. int slot = Random::integer(cw_);
  130. s.schedule(h, p, delay + slotTime_ * slot);
  131. cw_ = min(2 * cw_, cwmax_);
  132. }
  133. else
  134. resume(p);
  135. }
  136. void MacCsma::endofContention(Packet* p)
  137. {
  138. Scheduler& s = Scheduler::instance();
  139. double txt = txtime(p) - (s.clock() - txstart_);
  140. hdr_mac::access(p)->txtime() = txt;
  141. channel_->send(p, txt);
  142. s.schedule(&hRes_, &eEoc_, txt);
  143. rtx_ = 0;
  144. cw_ = cwmin_;
  145. }
  146. void MacCsmaCd::endofContention(Packet* p)
  147. {
  148. // If there is a collision, backoff
  149. if (channel_->collision()) {
  150. channel_->jam(0);
  151. backoff(&hSend_, p);
  152. }
  153. else
  154. MacCsma::endofContention(p);
  155. }
  156. void MacCsmaCa::send(Packet* p)
  157. {
  158. Scheduler& s = Scheduler::instance();
  159. double delay = channel_->txstop() + ifs_ - s.clock();
  160. if (csense_ && delay > 0)
  161. backoff(&hSend_, p);
  162. else {
  163. txstart_ = s.clock();
  164. channel_->contention(p, &hEoc_);
  165. }
  166. }