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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * mac-802_3.cc
  4.  * $Id: mac-802_3.cc,v 1.16 2002/06/14 23:15:03 yuri Exp $
  5.  */
  6. #include <packet.h>
  7. #include <random.h>
  8. #include <arp.h>
  9. #include <ll.h> 
  10. #include <mac-802_3.h>
  11. //#define MAC_DEBUG
  12. #ifndef MAC_DEBUG
  13. #define FPRINTF(s, f, t, index, func) do {} while (0)
  14. #else
  15.    static double xtime= 0.0;
  16. #  define FPRINTF(s, f, t, index, func) 
  17.          do { fprintf(s, f, t, index, func); xtime= t; } while (0)
  18. #endif //MAC_DEBUG
  19. #define PRNT_MAC_FUNCS(mac) 
  20. FPRINTF(stderr, "%.15f : %d : %sn", 
  21. Scheduler::instance().clock(), (mac)->index_, __PRETTY_FUNCTION__)
  22. inline void MacHandler::cancel() {
  23. PRNT_MAC_FUNCS(mac);
  24. Scheduler& s = Scheduler::instance();
  25. assert(busy_);
  26. s.cancel(&intr);
  27. // No need to free the event intr since it's statically allocated.
  28. busy_ = 0;
  29. }
  30. inline void Mac8023HandlerSend::cancel() {
  31. PRNT_MAC_FUNCS(mac);
  32. assert(busy_);
  33. Scheduler &s= Scheduler::instance();
  34. s.cancel(&intr);
  35. busy_= 0;
  36. p_= 0;
  37. }
  38. inline void MacHandlerRecv::cancel() {
  39. PRNT_MAC_FUNCS(mac);
  40. Scheduler& s = Scheduler::instance();
  41. assert(busy_ && p_);
  42. s.cancel(&intr);
  43. busy_ = 0;
  44. Packet::free(p_);
  45. p_= 0;
  46. }
  47. inline void MacHandlerRetx::cancel() {
  48. PRNT_MAC_FUNCS(mac);
  49. Scheduler& s = Scheduler::instance();
  50. assert(busy_ && p_);
  51. s.cancel(&intr);
  52. }
  53. inline void MacHandlerIFS::cancel() {
  54. PRNT_MAC_FUNCS(mac);
  55. //fprintf (stderr, "cancelled dtime= %.15fn", intr.time_- Scheduler::instance().clock());
  56. MacHandler::cancel();
  57. }
  58. static class Mac802_3Class : public TclClass {
  59. public:
  60. Mac802_3Class() : TclClass("Mac/802_3") {}
  61. TclObject* create(int, const char*const*) {
  62. return (new Mac802_3);
  63. }
  64. } class_mac802_3;
  65. void Mac8023HandlerSend::handle(Event*) {
  66. PRNT_MAC_FUNCS(mac);
  67. assert(p_);
  68. /* Transmission completed successfully */
  69. busy_ = 0;
  70. p_= 0;
  71. mac->mhRetx_.free();
  72. mac->mhRetx_.reset();
  73. mac->mhIFS_.schedule(mac->netif_->txtime(int(IEEE_8023_IFS_BITS/8.0)));
  74. }
  75. void Mac8023HandlerSend::schedule(const Packet *p, double t) {
  76. PRNT_MAC_FUNCS(mac);
  77. Scheduler& s = Scheduler::instance();
  78. assert(!busy_);
  79. s.schedule(this, &intr, t);
  80. busy_ = 1;
  81. p_= p;
  82. }
  83. void MacHandlerRecv::handle(Event* ) {
  84. /* Reception Successful */
  85. PRNT_MAC_FUNCS(mac);
  86. busy_ = 0;
  87. mac->recv_complete(p_);
  88. p_= 0;
  89. }
  90. void MacHandlerRecv::schedule(Packet *p, double t) {
  91. PRNT_MAC_FUNCS(mac);
  92. Scheduler& s = Scheduler::instance();
  93. assert(p && !busy_);
  94. s.schedule(this, &intr, t);
  95. busy_ = 1;
  96. p_ = p;
  97. }
  98. bool MacHandlerRetx::schedule(double delta) {
  99. PRNT_MAC_FUNCS(mac);
  100. Scheduler& s = Scheduler::instance();
  101. assert(p_ && !busy_);
  102. int k, r;
  103. if(try_ < IEEE_8023_ALIMIT) {
  104. k = min(try_, IEEE_8023_BLIMIT);
  105. r = Random::integer(1 << k);
  106. s.schedule(this, &intr, r * mac->netif_->txtime((int)(IEEE_8023_SLOT_BITS/8.0)) + delta);
  107. busy_ = 1;
  108. return true;
  109. }
  110. return false;
  111. }
  112. void MacHandlerRetx::handle(Event *) {
  113. PRNT_MAC_FUNCS(mac);
  114. assert(p_);
  115. busy_= 0;
  116. ++try_;
  117. mac->transmit(p_);
  118. }
  119. inline void MacHandlerIFS::schedule(double t) {
  120. PRNT_MAC_FUNCS(mac);
  121. assert(!busy_);
  122. Scheduler &s= Scheduler::instance();
  123. s.schedule(this, &intr, t);
  124. busy_= 1;
  125. }
  126. inline void MacHandlerIFS::handle(Event*) { 
  127. PRNT_MAC_FUNCS(mac);
  128. busy_= 0; 
  129. mac->resume(); 
  130. }
  131. Mac802_3::Mac802_3() : trace_(0), 
  132. mhRecv_(this), mhRetx_(this), mhIFS_(this), mhSend_(this) {
  133.         // Bind mac trace variable 
  134.         bind_bool("trace_",&trace_);
  135. }
  136. void Mac802_3::sendUp(Packet *p, Handler *) {
  137. PRNT_MAC_FUNCS(this);
  138. /* just received the 1st bit of a packet */
  139. if (state_ != MAC_IDLE && mhIFS_.busy()) {
  140. #define EPS 1.0e-15 /* can be considered controller clock resolution */
  141. if (mhIFS_.expire() - Scheduler::instance().clock() > EPS) {
  142. // This can happen when 3 nodes TX:
  143. // 1 was TX, then IFS, then TX again;
  144. // 2,3 were in RX (from 1), then IFS, then TX, then collision with 1 and IFS
  145. // while 3 in IFS it RX from 2 and vice versa.
  146. // We ignore it and let the ifs timer take care of things.
  147.         Packet::free(p);
  148. return;
  149. } else {
  150. // This means that mhIFS_ is about to expire now. We assume that IFS is over 
  151. // and resume, because we want to give this guy a chance - otherwise the guy 
  152. // who TX before will TX again (fairness); if we have anything to
  153. // TX, this forces a collision.
  154. mhIFS_.cancel();
  155. resume();
  156. }
  157. #undef EPS
  158. if(state_ == MAC_IDLE) {
  159. state_ = MAC_RECV;
  160. assert(!mhRecv_.busy());
  161. /* the last bit will arrive in txtime seconds */
  162. mhRecv_.schedule(p, netif_->txtime(p));
  163. } else {
  164. collision(p); //received packet while sending or receiving
  165. }
  166. }
  167. void Mac802_3::sendDown(Packet *p, Handler *h) {
  168. PRNT_MAC_FUNCS(this);
  169. assert(initialized());
  170. assert(h);
  171. assert(netif_->txtime(IEEE_8023_MINFRAME) > 
  172.        2*netif_->channel()->maxdelay()); /* max prop. delay is limited by specs: 
  173.     about 25us for 10Mbps
  174.     and   2.5us for 100Mbps
  175.  */
  176. int size= (HDR_CMN(p)->size() += ETHER_HDR_LEN); //XXX also preamble?
  177. hdr_mac *mh= HDR_MAC(p);
  178. mh->padding_= 0;
  179. if (size > IEEE_8023_MAXFRAME) {
  180. static bool warnedMAX= false;
  181. if (!warnedMAX) {
  182. fprintf(stderr, "Mac802_3: frame is too big: %dn", size);
  183. warnedMAX= true;
  184. }
  185. } else if (size < IEEE_8023_MINFRAME) {
  186. // pad it to fit MINFRAME
  187. mh->padding_= IEEE_8023_MINFRAME - size;
  188. HDR_CMN(p)->size() += mh->padding_;
  189. }
  190. callback_ = h;
  191. mhRetx_.packet(p); //packet's buffered by mhRetx in case of retransmissions
  192. transmit(p);
  193. }
  194. void Mac802_3::transmit(Packet *p) {
  195. PRNT_MAC_FUNCS(this);
  196. assert(callback_);
  197. if(mhSend_.packet()) {
  198. fprintf(stderr, "index: %dn", index_);
  199. fprintf(stderr, "Retx Timer: %dn", mhRetx_.busy());
  200. fprintf(stderr, "IFS  Timer: %dn", mhIFS_.busy());
  201. fprintf(stderr, "Recv Timer: %dn", mhRecv_.busy());
  202. fprintf(stderr, "Send Timer: %dn", mhSend_.busy());
  203. exit(1);
  204. }
  205. /* Perform carrier sense  - if we were sending before, never mind state_ */
  206. if (mhIFS_.busy() || (state_ != MAC_IDLE)) {
  207. /* we'll try again when IDLE. It'll happen either when
  208.                    reception completes, or if collision.  Either way,
  209.                    we call resume() */
  210. return;
  211. }
  212. double txtime = netif_->txtime(p);
  213. /* Schedule transmission of the packet's last bit */
  214. mhSend_.schedule(p, txtime);
  215. // pass the packet to the PHY: need to send a copy, 
  216. // because there may be collision and it may be freed
  217. Packet *newp = p->copy();
  218. HDR_CMN(newp)->direction()= hdr_cmn::DOWN; //down
  219. downtarget_->recv(newp);
  220. state_= MAC_SEND;
  221. }
  222. void Mac802_3::collision(Packet *p) {
  223. PRNT_MAC_FUNCS(this);
  224. if (mhIFS_.busy()) mhIFS_.cancel();
  225. double ifstime= netif_->txtime(int((IEEE_8023_JAMSIZE+IEEE_8023_IFS_BITS)/8.0)); //jam time + ifs
  226. mhIFS_.schedule(ifstime);
  227. switch(state_) {
  228. case MAC_SEND:
  229.   // If mac trace feature is on generate a collision trace for this packet. 
  230.         if (trace_)
  231.            drop(p);
  232.         else
  233.            Packet::free(p);
  234. if (mhSend_.busy()) mhSend_.cancel();
  235. if (!mhRetx_.busy()) {
  236. /* schedule retransmissions */
  237. if (!mhRetx_.schedule(ifstime)) {
  238. p= mhRetx_.packet();
  239. hdr_cmn *th = hdr_cmn::access(p);
  240. HDR_CMN(p)->size() -= (ETHER_HDR_LEN + HDR_MAC(p)->padding_);
  241. fprintf(stderr,"BEB limit exceeded:Dropping packet %dn",th->uid());
  242.                                 fflush(stderr);
  243. drop(p); // drop if backed off far enough
  244. mhRetx_.reset();
  245. }
  246. }
  247. break;
  248. case MAC_RECV:
  249.         Packet::free(p);
  250. // more than 2 packets collisions possible
  251. if (mhRecv_.busy()) mhRecv_.cancel();
  252. break;
  253. default:
  254. assert("SHOULD NEVER HAPPEN" == 0);
  255. }
  256. }
  257. void Mac802_3::recv_complete(Packet *p) {
  258. PRNT_MAC_FUNCS(this);
  259. assert(!mhRecv_.busy());
  260. assert(!mhSend_.busy());
  261. hdr_cmn *ch= HDR_CMN(p);
  262. /* Address Filtering */
  263. hdr_mac *mh= HDR_MAC(p);
  264. int dst= mh->macDA();
  265. if ((dst != BCAST_ADDR) && (dst != index_)) {
  266. Packet::free(p);
  267. goto done;
  268. }
  269. /* Strip off the mac header and padding if any */
  270. ch->size() -= (ETHER_HDR_LEN + mh->padding_);
  271. /* xxx FEC here */
  272. if( ch->error() ) {
  273.                 fprintf(stderr,"nChecksum errornDropping packet");
  274.                 fflush(stderr);
  275. // drop(p);
  276.                 Packet::free(p);
  277. goto done;
  278. }
  279. /* we could schedule an event to account for mac-delay */
  280. if ((p->ref_count() > 0) /* so the channel is using ref-copying */
  281.     && (dst == BCAST_ADDR)) {
  282. /* make a real copy only if broadcasting, otherwise
  283.  * all nodes except the receiver are going to free
  284.  * this packet 
  285.  */
  286. uptarget_->recv(p->copy(), (Handler*) 0);
  287. Packet::free(p); // this will decrement ref counter
  288. } else {
  289. uptarget_->recv(p, (Handler*) 0);
  290. }
  291.  done:
  292. mhIFS_.schedule(netif_->txtime(int(IEEE_8023_IFS_BITS/8.0)));// wait for one IFS, then resume
  293. }
  294. /* we call resume() in these cases:
  295.    - successful transmission
  296.    - whole packet's received
  297.    - collision and backoffLimit's exceeded
  298.    - collision while receiving */
  299. void Mac802_3::resume() {
  300. PRNT_MAC_FUNCS(this);
  301. assert(!mhRecv_.busy());
  302. assert(!mhSend_.busy());
  303. assert(!mhIFS_.busy());
  304. state_= MAC_IDLE;
  305. if (mhRetx_.packet()) {
  306. if (!mhRetx_.busy()) {
  307. // we're not backing off and not sensing carrier right now: send
  308. transmit(mhRetx_.packet());
  309. }
  310. } else {
  311. if (callback_ && !mhRetx_.busy()) {
  312. //WARNING: calling callback_->handle may change the value of callback_
  313. Handler* h= callback_; 
  314. callback_= 0;
  315. h->handle(0);
  316. }
  317. }
  318. }