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 #ifndef lint
00038 static const char rcsid[] =
00039 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/mac.cc,v 1.39 2001/06/05 23:49:43 haldar Exp $ (UCB)";
00040 #endif
00041
00042
00043
00044 #include <channel.h>
00045 #include <mac.h>
00046 #include <address.h>
00047
00048 int hdr_mac::offset_;
00049 static class MacHeaderClass : public PacketHeaderClass {
00050 public:
00051 MacHeaderClass() : PacketHeaderClass("PacketHeader/Mac",
00052 sizeof(hdr_mac)) {
00053 bind_offset(&hdr_mac::offset_);
00054 }
00055 void export_offsets() {
00056 field_offset("macSA_", OFFSET(hdr_mac, macSA_));
00057 field_offset("macDA_", OFFSET(hdr_mac, macDA_));
00058 }
00059 } class_hdr_mac;
00060
00061 static class MacClass : public TclClass {
00062 public:
00063 MacClass() : TclClass("Mac") {}
00064 TclObject* create(int, const char*const*) {
00065 return (new Mac);
00066 }
00067 } class_mac;
00068
00069
00070 void
00071 MacHandlerResume::handle(Event*)
00072 {
00073 mac_->resume();
00074 }
00075
00076 void
00077 MacHandlerSend::handle(Event* e)
00078 {
00079 mac_->sendDown((Packet*)e);
00080 }
00081
00082
00083
00084
00085 static int MacIndex = 0;
00086
00087 Mac::Mac() :
00088 BiConnector(), abstract_(0), netif_(0), tap_(0), ll_(0), channel_(0), callback_(0),
00089 hRes_(this), hSend_(this), state_(MAC_IDLE), pktRx_(0), pktTx_(0)
00090 {
00091 index_ = MacIndex++;
00092 bind_bw("bandwidth_", &bandwidth_);
00093 bind_time("delay_", &delay_);
00094 bind_bool("abstract_", &abstract_);
00095 }
00096
00097 int Mac::command(int argc, const char*const* argv)
00098 {
00099 if(argc == 2) {
00100 Tcl& tcl = Tcl::instance();
00101
00102 if(strcmp(argv[1], "id") == 0) {
00103 tcl.resultf("%d", addr());
00104 return TCL_OK;
00105 } else if (strcmp(argv[1], "channel") == 0) {
00106 tcl.resultf("%s", channel_->name());
00107 return (TCL_OK);
00108 }
00109
00110 } else if (argc == 3) {
00111 TclObject *obj;
00112 if( (obj = TclObject::lookup(argv[2])) == 0) {
00113 fprintf(stderr, "%s lookup failed\n", argv[1]);
00114 return TCL_ERROR;
00115 }
00116 else if (strcmp(argv[1], "netif") == 0) {
00117 netif_ = (Phy*) obj;
00118 return TCL_OK;
00119 }
00120 else if (strcmp(argv[1], "log-target") == 0) {
00121 logtarget_ = (NsObject*) obj;
00122 if(logtarget_ == 0)
00123 return TCL_ERROR;
00124 return TCL_OK;
00125 }
00126 }
00127
00128 return BiConnector::command(argc, argv);
00129 }
00130
00131 void Mac::recv(Packet* p, Handler* h)
00132 {
00133 if (hdr_cmn::access(p)->direction() == hdr_cmn::UP) {
00134 sendUp(p);
00135 return;
00136 }
00137
00138 callback_ = h;
00139 hdr_mac* mh = HDR_MAC(p);
00140 mh->set(MF_DATA, index_);
00141 state(MAC_SEND);
00142 sendDown(p);
00143 }
00144
00145 void Mac::sendUp(Packet* p)
00146 {
00147 char* mh = (char*)p->access(hdr_mac::offset_);
00148 int dst = this->hdr_dst(mh);
00149
00150 state(MAC_IDLE);
00151 if (((u_int32_t)dst != MAC_BROADCAST) && (dst != index_)) {
00152 if(!abstract_){
00153 drop(p);
00154 }else {
00155
00156 Packet::free(p);
00157 }
00158 return;
00159 }
00160 Scheduler::instance().schedule(uptarget_, p, delay_);
00161 }
00162
00163 void Mac::sendDown(Packet* p)
00164 {
00165 Scheduler& s = Scheduler::instance();
00166 double txt = txtime(p);
00167 downtarget_->recv(p, this);
00168 if(!abstract_)
00169 s.schedule(&hRes_, &intr_, txt);
00170 }
00171
00172
00173 void Mac::resume(Packet* p)
00174 {
00175 if (p != 0)
00176 drop(p);
00177 state(MAC_IDLE);
00178 callback_->handle(&intr_);
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195