802.11 Backoff Timer,bugFix_timer_

本文主要介绍802.11协议中的退避算法的具体流程:


上图出自802.11-2007的文档,简单明了的解释了各个node在竞争信道时发生的故事。

下面两段代码对应802.11的send函数和resume函数:

send函数部分代码:

/*
	 *  If the medium is IDLE, we must wait for a DIFS
	 *  Space before transmitting.
	 */
	if(mhBackoff_.busy() == 0) {
		if(is_idle()) {
			if (mhDefer_.busy() == 0) {
				/*
				 * If we are already deferring, there is no
				 * need to reset the Defer timer.
				 */
				if (bugFix_timer_) {
					 mhBackoff_.start(cw_, is_idle(), 
							  phymib_.getDIFS());
				}
				else {
					rTime = (Random::random() % cw_)
						* (phymib_.getSlotTime());
					mhDefer_.start(phymib_.getDIFS() + 
						       rTime);
				}
			}
		} else {
			/*
			 * If the medium is NOT IDLE, then we start
			 * the backoff timer.
			 */
			mhBackoff_.start(cw_, is_idle());
		}
	}
}
当一个node准备send之前,首先要检查自己的backoff timer是否已经开始倒计时,如果已经开始倒计时,那么只要return等待timer的结束即可。因为任何情况下只要mhBackoff timer结束,此node就可以立即占用信道。这对应于node第一行中的判断。


tx_resume()部分代码:

if (mhBackoff_.busy() == 0) {//waiting for backoff timer times out at which time we can send data right now
			if (bugFix_timer_) {
				mhBackoff_.start(cw_, is_idle(), 
						 phymib_.getDIFS());//
			}
			else {
				rTime = (Random::random() % cw_) * 
					phymib_.getSlotTime();
				mhDefer_.start( phymib_.getDIFS() + rTime);
			}
		}

首先,对于node B 来说,他首先check自己的mhBackoff timer,发现not busy;接着检查信道是否空闲(is_idle()),此时因为上图中信道被A占据,信道忙,所以B被迫进入defer阶段,等待信道的再次空闲。此时,对应的代码段因为is_idle()判断为否,直接进入else 语句中,设定自己的Backoff timer。这里为什么本来要进入defer timer却要设置Backoff Timer呢?主要是由于Backoff Timer的class确定的。

解释:1.在backoff timer被设置为cw_的瞬间,由于第二个参数is_idle()为0,start()函数会立即将paused_设为1,即立即暂停backoff timer,所以此时实际上并不会开始倒计时,而是要等到resume()函数被唤醒之后才会继续。

2.start(cw_, is_idle())这句有两个疑点。第一,backoff的时间应该是random%cw_*slottime而不是固定的cw_; 第二,在被唤醒之后,除了等待random的backoff 时间,802.11中规定了首先要冻结DIFS之后才可以倒计时backoff timer. 事实上,这两点分别在mac-timers.cc中的BackoffTimer::start(int cw, int idle, double difs) 和BackoffTimer::resume(double difs)中给出了解释。即backoff的时间是在start()中设置的,而resume之后的DIFS是在resume()中加入的。

对于node C和D也是采取同样的措施。

那么,当信道为空闲时,B、C、D的backoff timer同时被唤醒,执行resume()函数,首先等待DIFS,接着开始timer的countdown,由于C比较幸运,backoff timer率先结束,于是直接占用信道。此时,信道状态变为忙,于是B和D的backoff timer也被迫暂停(图中backoff的灰色部分表示剩余的冻结时间),直到C的数据传输完毕。重复以上过程,接下来D、E和B分别占用信道,整个过程结束。

对于NS2 send()函数中剩余部分的解释如下:

拿下图来说,我们假定此时node B还没有backoff,即忽略下图中Frame前面的那一小段backoff;并且假定node B将要开始传送数据时信道为空闲状态。

那么,对应上述代码,首先check mhBackoff为闲,接着check  is_idle()为真,进入mhDefer的判断。如果defer timer已经被前面的将要send出去的数据包设置过了,那么就无需再设,只需要等待他的time out即可。否则的话,开始设置占用信道的backoff timer.这时候引入了一个bugFix_timer_的标志,具体参见点击打开链接 此文。

在NS2的default.tcl的设置中,bugFix_timer_是设为真的,所以这时候我们就直接进入mhBackoff_.start(),开始倒计时。但是注意,这时候start()函数里加了一个phymib_.getDIFS(),即加入了一个difs,这与上文所述并不矛盾。因为,上文中所述,信道正处于忙碌状态,backoff 会立即暂停并在resume后由resume()函数加入difs;但此时由于信道为空闲,backoff timer会立即启动,那么自然要手动加入这个difs了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值