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

通讯编程

开发平台:

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 research group 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. #ifndef lint
  35. static const char rcsid[] =
  36.     "@(#) $Header: /cvsroot/nsnam/ns-2/mac/mac-multihop.cc,v 1.14 2000/11/02 22:46:37 johnh Exp $ (UCB)";
  37. #endif
  38. #include "template.h"
  39. #include "channel.h"
  40. #include "mac-multihop.h"
  41. /* 
  42.  * For debugging.
  43.  */
  44. void dump_iphdr(hdr_ip *iph) 
  45. {
  46.         printf("tsrc = %d, ", iph->saddr());
  47.         printf("tdst = %dn", iph->daddr());
  48. }       
  49. static class MultihopMacClass : public TclClass {
  50. public:
  51. MultihopMacClass() : TclClass("Mac/Multihop") {}
  52. TclObject* create(int, const char*const*) {
  53. return (new MultihopMac);
  54. }
  55. } class_mac_multihop;
  56. MultihopMac::MultihopMac() : mode_(MAC_IDLE), peer_(0),
  57. pendingPollEvent_(0), pkt_(0),
  58. ph_(this), pah_(this), pnh_(this), pth_(this), bh_(this)
  59. {
  60. /* Bind a bunch of variables to access from Tcl */
  61. bind_time("tx_rx_", &tx_rx_);
  62. bind_time("rx_tx_", &rx_tx_);
  63. bind_time("rx_rx_", &rx_rx_);
  64. bind_time("backoffBase_", &backoffBase_);
  65. backoffTime_ = backoffBase_;
  66. }
  67. /*
  68.  * Returns 1 iff the specified MAC is in the prescribed state, AND all
  69.  * the other MACs are IDLE.
  70.  */
  71. int MultihopMac::checkInterfaces(int state) 
  72. {
  73. MultihopMac *p;
  74. if (!(mode_ & state))
  75. return 0;
  76. else if (macList_ == 0)
  77. return 1;
  78. for (p = (MultihopMac *)macList_; p != this && p != NULL; 
  79.      p = (MultihopMac *)(p->macList())) {
  80. if (p->mode() != MAC_IDLE) {
  81. return 0;
  82. }
  83. }
  84. return 1;
  85. }
  86. /*
  87.  * Poll a peer node prior to a send.  There can be at most one POLL 
  88.  * outstanding from a node at any point in time.  This is achieved implicitly
  89.  * because there can be at most one packet down from LL (thru IFQ) to this MAC.
  90.  */
  91. void MultihopMac::poll(Packet *p)
  92. {
  93. Scheduler& s = Scheduler::instance();
  94. MultihopMac *pm = (MultihopMac*) getPeerMac(p);
  95. PollEvent *pe = new PollEvent(pm, this);
  96. pendingPollEvent_ = new PollEvent(pm, this);
  97. pkt_ = p->copy(); /* local copy for poll retries */
  98. double timeout = max(pm->rx_tx(), tx_rx_) + 4*pollTxtime(MAC_POLLSIZE);
  99. s.schedule(&bh_, pendingPollEvent_, timeout);
  100. /*  If the other interfaces are idle, then go ahead, else not. */
  101. if (checkInterfaces(MAC_IDLE)) { 
  102. mode_ = MAC_POLLING;
  103. peer_ = pm;
  104. s.schedule(pm->ph(), (Event *)pe, pollTxtime(MAC_POLLSIZE));
  105. }
  106. }
  107. /*
  108.  * Handle a POLL request from a peer node's MAC.
  109.  */
  110. void
  111. PollHandler::handle(Event *e)
  112. {
  113. PollEvent *pe = (PollEvent *) e;
  114. Scheduler& s = Scheduler::instance();
  115. MultihopMac* pm = mac_->peer(); /* sensible val only in MAC_RCV mode */
  116. /*
  117.  * Send POLLACK if either IDLE or currently receiving 
  118.  * from same mac as the poller.
  119.  */
  120. if (mac_->checkInterfaces(MAC_IDLE)) { // all interfaces must be IDLE
  121. mac_->mode(MAC_RCV);
  122. pm = pe->peerMac();
  123. mac_->peer(pm);
  124. PollEvent *pae = new PollEvent(pm, mac_); // POLLACK event
  125. double t = mac_->pollTxtime(MAC_POLLACKSIZE) + 
  126. max(mac_->tx_rx(), pm->rx_tx());
  127. s.schedule(pm->pah(), pae, t);
  128. } else {
  129. // printf("ignoring poll %dn", mac_->label());
  130. // could send NACKPOLL but don't (at least for now)
  131. }
  132. }
  133. /*
  134.  * Handle a POLLACK from a peer node's MAC.
  135.  */
  136. void
  137. PollAckHandler::handle(Event *e)
  138. {
  139. PollEvent *pe = (PollEvent *) e;
  140. Scheduler& s = Scheduler::instance();
  141. if (mac_->checkInterfaces(MAC_POLLING | MAC_IDLE)) {
  142. mac_->backoffTime(mac_->backoffBase());
  143. mac_->mode(MAC_SND);
  144. mac_->peer(pe->peerMac());
  145. s.cancel(mac_->pendingPE()); /* cancel pending timeout */
  146. free(mac_->pendingPE());  // and free the event
  147. mac_->pendingPE(NULL);
  148. mac_->send(mac_->pkt()); /* send saved packet */
  149. }
  150. }
  151. void
  152. PollNackHandler::handle(Event *)
  153. {
  154. }
  155. void
  156. BackoffHandler::handle(Event *)
  157. {
  158. Scheduler& s = Scheduler::instance();
  159. if (mac_->mode() == MAC_POLLING) 
  160. mac_->mode(MAC_IDLE);
  161. double bTime = mac_->backoffTime(2*mac_->backoffTime());
  162. bTime = (1+Random::integer(MAC_TICK)*1./MAC_TICK)*bTime + 
  163. 2*mac_->backoffBase();
  164. // printf("backing off %dn", mac_->label());
  165. s.schedule(mac_->pth(), mac_->pendingPE(), bTime);
  166. }
  167. void 
  168. PollTimeoutHandler::handle(Event *)
  169. {
  170. mac_->poll(mac_->pkt());
  171. }
  172. /*
  173.  * Actually send the data frame.
  174.  */
  175. void MultihopMac::send(Packet *p)
  176. {
  177. Scheduler& s = Scheduler::instance();
  178. if (mode_ != MAC_SND)
  179. return;
  180. double txt = txtime(p);
  181. hdr_mac::access(p)->txtime() = txt;
  182. channel_->send(p, txt); // target is peer's mac handler
  183. s.schedule(callback_, &intr_, txt); // callback to higher layer (LL)
  184. mode_ = MAC_IDLE;
  185. }
  186. /*
  187.  * This is the call from the higher layer of the protocol stack (i.e., LL)
  188.  */
  189. void MultihopMac::recv(Packet* p, Handler *h)
  190. {
  191. if (h == 0) { /* from MAC classifier (pass pkt to LL) */
  192. mode_ = MAC_IDLE;
  193. Scheduler::instance().schedule(target_, p, delay_);
  194. return;
  195. }
  196. callback_ = h;
  197. hdr_mac* mh = hdr_mac::access(p);
  198. mh->macSA() = addr_;
  199. if (mh->ftype() == MF_ACK) {
  200. mode_ = MAC_SND;
  201. send(p);
  202. } else {
  203. mh->ftype() = MF_DATA;
  204. poll(p); /* poll first */
  205. }
  206. }