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
00042 #include<mac.h>
00043 #include"mmac-csma.h"
00044 #include<iostream>
00045
00046 #define DEBUG_UNEXPECTED_EVENT { std::cerr << showpoint << NOW << " (" << addr << ") unexpected event " << __PRETTY_FUNCTION__ << " in state " << state_name_array[state].name << std::endl ; exit(1); }
00047 #define DEBUG_EVENT { if (debug_states_) std::cerr << showpoint << NOW << " MMacCsma " << addr << " : event " << __FUNCTION__ << std::endl; }
00048
00049 packet_t PT_MMAC_ACK;
00050
00051 struct state_name {
00052 enum MMAC_CSMA_STATE state;
00053 const char* name;
00054 } state_name_array[NUM_MMAC_CSMA_STATES] = {
00055 {STATE_IDLE, "IDLE"},
00056 {STATE_RX_DATA, "RX_DATA"},
00057 {STATE_TX_ACK, "TX_ACK"},
00058 {STATE_CHK_PENDING_PKT, "CHK_PENDING_PKT"},
00059 {STATE_CHK_FROZEN_BACKOFF, "CHK_FROZEN_BACKOFF"},
00060 {STATE_BACKOFF, "BACKOFF"},
00061 {STATE_FREEZE_BACKOFF, "FREEZE_BACKOFF"},
00062 {STATE_TX_DATA, "TX_DATA"},
00063 {STATE_START_ACK_TIMEOUT, "START_ACK_TIMEOUT"},
00064 {STATE_WAIT_ACK, "WAIT_ACK"},
00065 {STATE_RX_ACK, "RX_ACK"},
00066 {STATE_CHK_ACK_TIMEOUT_EXPIRED, "CHK_ACK_TIMEOUT_EXPIRED"},
00067 {STATE_TX_SUCCESSFUL, "TX_SUCCESSFUL"},
00068 {STATE_TX_FAILED, "TX_FAILED"}
00069 };
00070
00071
00072 static class MMacCsmaClass : public TclClass {
00073 public:
00074 MMacCsmaClass() : TclClass("Module/MMac/CSMA") {}
00075 TclObject* create(int, const char*const*) {
00076 return (new MMacCsma);
00077 }
00078 } class_MMacCsma;
00079
00080
00081
00082 int MMacCsma::uidcnt = 1000;
00083
00084 MMacCsma::MMacCsma()
00085 : backoff_timer(this),
00086 ack_timer(this),
00087 ConsecutiveFailedTxAttempts(0),
00088 PktTx(0),
00089 PktRx(0),
00090 state(STATE_IDLE)
00091 {
00092 bind("HeaderSize_",&HeaderSize_);
00093 bind("BaseBackoffTime_",&BaseBackoffTime_);
00094 bind("AckTimeout_",&AckTimeout_);
00095 bind("debug_states_",&debug_states_);
00096
00097 }
00098
00099
00100 bool MMacCsma::FrozenBackoff()
00101 {
00102 return backoff_timer.isFrozen();
00103 }
00104
00105
00106 bool MMacCsma::PendingPacket()
00107 {
00108 if (PktTx)
00109 return true;
00110 else if (!Q.empty())
00111 {
00112 PktTx = Q.front();
00113 Q.pop();
00114 return true;
00115 }
00116 else
00117 return false;
00118 }
00119
00120 void MMacCsma::recvFromUpperLayers(Packet* p)
00121 {
00122 DEBUG_EVENT;
00123 switch (state)
00124 {
00125 case STATE_IDLE:
00126 assert(Q.empty());
00127 assert(PktTx == NULL);
00128 assert(PendingPacket() == false);
00129 PktTx = p;
00130 enterState_TX_DATA();
00131 break;
00132 default:
00133 if (PktTx == NULL)
00134 PktTx = p;
00135 else
00136 Q.push(p);
00137 break;
00138 }
00139 }
00140
00141 void MMacCsma::Phy2MacEndTx(const Packet* p)
00142 {
00143 DEBUG_EVENT;
00144 switch (state)
00145 {
00146 case STATE_TX_DATA:
00147 enterState_START_ACK_TIMEOUT();
00148 break;
00149 case STATE_TX_ACK:
00150 enterState_CHK_PENDING_PKT();
00151 break;
00152 default:
00153 DEBUG_UNEXPECTED_EVENT;
00154 break;
00155 }
00156 }
00157
00158 void MMacCsma::Phy2MacStartRx(const Packet* p)
00159 {
00160 DEBUG_EVENT;
00161 assert(PktRx == NULL);
00162 PktRx = p;
00163 switch (state)
00164 {
00165 case STATE_IDLE:
00166 enterState_RX_DATA();
00167 break;
00168 case STATE_WAIT_ACK:
00169 enterState_RX_ACK();
00170 break;
00171 case STATE_BACKOFF:
00172 enterState_FREEZE_BACKOFF();
00173 break;
00174 default:
00175 DEBUG_UNEXPECTED_EVENT;
00176 break;
00177 }
00178 }
00179
00180
00181 void MMacCsma::Phy2MacEndRx(Packet* p)
00182 {
00183 DEBUG_EVENT;
00184
00185 hdr_cmn* ch = hdr_cmn::access(p);
00186 hdr_mac *mh = HDR_MAC(p);
00187
00188 assert(PktRx == p);
00189 PktRx = NULL;
00190
00191 if (ch->error())
00192 {
00193 recvWhateverElse(p);
00194 }
00195 else
00196 {
00197
00198 if(mh->macDA() == addr)
00199 {
00200 if(ch->ptype() == PT_MMAC_ACK)
00201 recvAck4Me(p);
00202 else
00203 recvData4Me(p);
00204 }
00205 else
00206 {
00207
00208 recvWhateverElse(p);
00209 }
00210 }
00211 }
00212
00213 void MMacCsma::recvData4Me(Packet* p)
00214 {
00215 DEBUG_EVENT;
00216 hdr_mac *mh = HDR_MAC(p);
00217 switch (state)
00218 {
00219 case STATE_RX_DATA:
00220 enterState_TX_ACK(mh->macSA());
00221 sendUp(p);
00222 break;
00223 default:
00224 recvWhateverElse(p);
00225 break;
00226 }
00227 }
00228
00229 void MMacCsma::recvAck4Me(Packet* p)
00230 {
00231 DEBUG_EVENT;
00232 switch (state)
00233 {
00234 case STATE_RX_ACK:
00235 Packet::free(p);
00236 enterState_TX_SUCCESSFUL();
00237 break;
00238 default:
00239 recvWhateverElse(p);
00240 break;
00241 }
00242 }
00243
00244
00245 void MMacCsma::recvWhateverElse(Packet* p)
00246 {
00247 DEBUG_EVENT;
00248 Packet::free(p);
00249 switch (state)
00250 {
00251 case STATE_RX_DATA:
00252 enterState_CHK_PENDING_PKT();
00253 break;
00254 case STATE_RX_ACK:
00255 enterState_CHK_ACK_TIMEOUT_EXPIRED();
00256 break;
00257 default:
00258 DEBUG_UNEXPECTED_EVENT;
00259 break;
00260 }
00261 }
00262
00263
00264 void MMacCsma::AckTimeout()
00265 {
00266 DEBUG_EVENT;
00267 switch (state)
00268 {
00269 case STATE_WAIT_ACK:
00270 enterState_TX_FAILED();
00271 break;
00272 case STATE_RX_ACK:
00273
00274 break;
00275 default:
00276 DEBUG_UNEXPECTED_EVENT;
00277 break;
00278 }
00279 }
00280
00281 void MMacCsma::BackoffEnded()
00282 {
00283 DEBUG_EVENT;
00284 switch (state)
00285 {
00286 case STATE_BACKOFF:
00287 enterState_TX_DATA();
00288 break;
00289 default:
00290 DEBUG_UNEXPECTED_EVENT;
00291 break;
00292 }
00293 }
00294
00295 void MMacCsma::setState(enum MMAC_CSMA_STATE s)
00296 {
00297 state = s;
00298 if (debug_states_)
00299 std::cerr << showpoint << NOW
00300 << " MMacCsma " << addr << " : entering state "
00301 << state_name_array[s].name
00302
00303
00304 << std::endl;
00305 }
00306
00307 void MMacCsma::enterState_IDLE()
00308 {
00309 assert(STATE_CHK_PENDING_PKT == state);
00310 assert(PktRx == NULL);
00311 assert(PktTx == NULL);
00312 setState(STATE_IDLE);
00313 }
00314
00315
00316 void MMacCsma::enterState_RX_DATA()
00317 {
00318 assert((STATE_IDLE == state)
00319 ||(STATE_FREEZE_BACKOFF == state));
00320 setState(STATE_RX_DATA);
00321 assert(PktRx != NULL);
00322 }
00323
00324 void MMacCsma::enterState_TX_ACK(int macSA_of_data_pkt)
00325 {
00326 assert(STATE_RX_DATA == state);
00327 setState(STATE_TX_ACK);
00328 Packet* p = Packet::alloc();
00329 hdr_cmn* ch = hdr_cmn::access(p);
00330
00331
00332 ch->size() = HeaderSize_;
00333 assert(ch->size() > 0);
00334
00335 hdr_mac *ack_mh = HDR_MAC(p);
00336 ack_mh->macSA() = addr;
00337 ack_mh->macDA() = macSA_of_data_pkt;
00338 Mac2PhyStartTx(p);
00339 }
00340
00341
00342 void MMacCsma::enterState_CHK_PENDING_PKT()
00343 {
00344 assert((STATE_RX_DATA == state)
00345 ||(STATE_TX_ACK == state)
00346 ||(STATE_TX_SUCCESSFUL == state));
00347 setState(STATE_CHK_PENDING_PKT);
00348 if(PendingPacket())
00349 enterState_CHK_FROZEN_BACKOFF();
00350 else
00351 enterState_IDLE();
00352 }
00353
00354 void MMacCsma::enterState_CHK_FROZEN_BACKOFF()
00355 {
00356 assert(STATE_CHK_PENDING_PKT == state);
00357 setState(STATE_CHK_FROZEN_BACKOFF);
00358 if(FrozenBackoff())
00359 enterState_BACKOFF();
00360 else
00361 enterState_TX_DATA();
00362 }
00363
00364
00365 void MMacCsma::enterState_BACKOFF()
00366 {
00367 assert((STATE_CHK_FROZEN_BACKOFF == state)
00368 ||(STATE_TX_FAILED == state));
00369 setState(STATE_BACKOFF);
00370 if (backoff_timer.isFrozen())
00371 backoff_timer.defrost();
00372 else
00373 backoff_timer.start(BaseBackoffTime_*pow(2,ConsecutiveFailedTxAttempts));
00374 }
00375
00376
00377 void MMacCsma::enterState_FREEZE_BACKOFF()
00378 {
00379 assert(STATE_BACKOFF == state);
00380 setState(STATE_FREEZE_BACKOFF);
00381 backoff_timer.freeze();
00382 enterState_RX_DATA();
00383 }
00384
00385 void MMacCsma::enterState_TX_DATA()
00386 {
00387 assert((STATE_BACKOFF == state)
00388 ||(STATE_CHK_FROZEN_BACKOFF == state)
00389 ||(STATE_IDLE == state));
00390 setState(STATE_TX_DATA);
00391 assert(PktTx);
00392 Mac2PhyStartTx(PktTx->copy());
00393 }
00394
00395
00396 void MMacCsma::enterState_START_ACK_TIMEOUT()
00397 {
00398 assert(STATE_TX_DATA == state);
00399 setState(STATE_START_ACK_TIMEOUT);
00400 ack_timer.start(AckTimeout_);
00401 enterState_WAIT_ACK();
00402 }
00403
00404
00405 void MMacCsma::enterState_WAIT_ACK()
00406 {
00407 assert((STATE_START_ACK_TIMEOUT == state)
00408 ||(STATE_CHK_ACK_TIMEOUT_EXPIRED == state));
00409 setState(STATE_WAIT_ACK);
00410 }
00411
00412 void MMacCsma::enterState_RX_ACK()
00413 {
00414 assert(STATE_WAIT_ACK == state);
00415 setState(STATE_RX_ACK);
00416 }
00417
00418 void MMacCsma::enterState_CHK_ACK_TIMEOUT_EXPIRED()
00419 {
00420 assert(STATE_RX_ACK == state);
00421 setState(STATE_CHK_ACK_TIMEOUT_EXPIRED);
00422 if(ack_timer.isExpired())
00423 enterState_TX_FAILED();
00424 else
00425 enterState_WAIT_ACK();
00426 }
00427
00428 void MMacCsma::enterState_TX_SUCCESSFUL()
00429 {
00430 assert(STATE_RX_ACK == state);
00431 setState(STATE_TX_SUCCESSFUL);
00432 ack_timer.stop();
00433 PktTx = NULL;
00434 ConsecutiveFailedTxAttempts = 0;
00435 enterState_CHK_PENDING_PKT();
00436 }
00437
00438 void MMacCsma::enterState_TX_FAILED()
00439 {
00440 assert((STATE_WAIT_ACK == state)
00441 ||(STATE_WAIT_ACK == state));
00442 setState(STATE_TX_FAILED);
00443
00444 ConsecutiveFailedTxAttempts++;
00445 enterState_BACKOFF();
00446 }
00447
00448
00449
00450 Backoff_Timer::Backoff_Timer(MMacCsma *m)
00451 : status(STATUS_STOPPED),
00452 mac(m)
00453 {
00454 }
00455
00456 void Backoff_Timer::start(double duration)
00457 {
00458 assert(status == STATUS_STOPPED);
00459 start_time = NOW;
00460 sched(duration);
00461 status = STATUS_RUNNING;
00462 }
00463
00464 void Backoff_Timer::freeze()
00465 {
00466 assert(status == STATUS_RUNNING);
00467 left_duration = NOW - start_time;
00468 cancel();
00469 status = STATUS_FROZEN;
00470 }
00471
00472
00473 void Backoff_Timer::defrost()
00474 {
00475 assert(status == STATUS_FROZEN);
00476 start_time = NOW;
00477 assert(left_duration > 0);
00478 sched(left_duration);
00479 status = STATUS_RUNNING;
00480 }
00481
00482 void Backoff_Timer::expire(Event *e)
00483 {
00484 assert(status == STATUS_RUNNING);
00485 status = STATUS_STOPPED;
00486 mac->BackoffEnded();
00487
00488 }
00489
00490 bool Backoff_Timer::isFrozen()
00491 {
00492 return (STATUS_FROZEN == status);
00493 }
00494
00495
00496
00497
00498
00499 Ack_Timer::Ack_Timer(MMacCsma *m)
00500 : status(STATUS_STOPPED),
00501 mac(m)
00502 {
00503 }
00504
00505 void Ack_Timer::start(double duration)
00506 {
00507 assert(status == STATUS_STOPPED);
00508 sched(duration);
00509 status = STATUS_RUNNING;
00510 }
00511
00512 void Ack_Timer::expire(Event *e)
00513 {
00514 assert(status == STATUS_RUNNING);
00515 mac->AckTimeout();
00516 status = STATUS_STOPPED;
00517 }
00518
00519 bool Ack_Timer::isExpired()
00520 {
00521 return (STATUS_STOPPED == status);
00522 }
00523
00524 void Ack_Timer::stop()
00525 {
00526 assert(status == STATUS_RUNNING);
00527 cancel();
00528 status = STATUS_STOPPED;
00529 }