80211 TIM流量指示图 附C语言实现

TIM是什么?

TIM:Traffic Indication Map,流量指示图。
在80211协议节能模式中,AP会缓存下行数据,AP就是通过beacon帧中TIM来告知休眠中的STA有数据需要接收。
DTIM:Delivery Traffic Indication Map,是一种特殊的TIM,其除了缓存的单播信息,也同时指示AP缓存的组播信息。

TIM格式

TIM IE包含了四个域:DTIM Count, DTIM Period, Bitmap Control, and Partial Virtual
Bitmap。
在这里插入图片描述

Length:1byte,表示TIM的长度。
DTIM Count:1byte,表示下次DTIM之前还有多少个beacon帧(包括当前的beacon帧),如果DTIM Count为0表示当前的TIM就是DTIM。
DTIM Period:1byte,表示两个DTIM之间有多少个beacon帧。1表示所有的TIM都是DTIM。
Bitmap Control:1byte,bit0表示是否有组播/广播数据包缓存,1表示有组播/广播数据包缓存,0表示没有。bit1-7表示bitmap的偏移情况,即Partial Virtual Bitmap起始值是多少。
Partial virtual Bitmap:1-251byte,以Bitmap Control的起始值开始的bitmap。可以表示的范围0~2007。

TIM编码例子

第一个例子,AP没有缓存组播/广播的下行数据,只缓存了STA AID 2和AID 7的数据。其中Bitmap Control为0x00,Partial Virtual Bitmap为0x84。
在这里插入图片描述

运行结果:
在这里插入图片描述

第二个例子,AP缓存了组播/广播的下行数据,还缓存了STA AID 2, AID 7, AID 22和AID 24的数据。
在这里插入图片描述

运行结果:
在这里插入图片描述

第三个例子,AP缓存了组播/广播的下行数据,还缓存了STA AID 24的数据。
在这里插入图片描述
运行结果:
在这里插入图片描述

TIM C语言实现demo

#include <stdio.h>
#define ADD_TIM_BIT 0
#define REMOVE_TIM_BIT 1
#define TIM_ELEMENT_ID 5
#define TIM_BASE_SIZE 3 /* size of TIM fields */
#define AID_SIZE 2008 /* valid AIDs are 1 thru 2007 */
#define VBM_SIZE 251 /* size of VBM array = 2008/8 = 251 */
typedef unsigned char UINT8;
typedef unsigned short int UINT16;

struct _tim
{
	UINT8 Element_id;
	UINT8 IELength;
	UINT8 DtimCount;
	UINT8 DtimPeriod;
	UINT8 BitMapControl;
	UINT8 PartialVirtualBitMap[VBM_SIZE];
};

UINT8 virtualBitMap[VBM_SIZE];
UINT8 mcast_pending = 0;
UINT8 dtimCount = 0;
UINT8 dtimPeriod = 5;

void Build_TIM(struct _tim * Tim)
{
	UINT8 octetIndex;
	UINT8 offset = 0;
	UINT8 lengthOfPartialVirtualBitMap = 0;
	/* Find first nonzero octet in the virtual bit map */
	for (octetIndex = 0; ((virtualBitMap[octetIndex] == 0) && (octetIndex < VBM_SIZE)); octetIndex++)
		/* empty */;
	if (octetIndex < VBM_SIZE)
		/* Clear the lsb as it is reserved for the broadcast/ multicast indication bit */
		offset = octetIndex & 0xFE;
	/* Find last nonzero octet in the virtual bit map */
	for (octetIndex = (VBM_SIZE - 1); ((virtualBitMap[octetIndex] == 0) && (octetIndex > 0)); octetIndex--)
		/* empty */;
	lengthOfPartialVirtualBitMap = octetIndex - offset + 1;
	Tim->Element_id = TIM_ELEMENT_ID;
	Tim->IELength = lengthOfPartialVirtualBitMap + TIM_BASE_SIZE;
	Tim->DtimCount = dtimCount;
	Tim->DtimPeriod = dtimPeriod;
	Tim->BitMapControl = offset;
	/* Update broadcast/ multicast indication bit if necessary */
	if ((Tim->DtimCount == 0) && mcast_pending)
		Tim->BitMapControl |= 0x01;
	/* Copy the virtual bit map octets that are nonzero */
	/* Note: A NULL virtualBitMap will still add a single octet of zero */
	for (octetIndex = 0; octetIndex < lengthOfPartialVirtualBitMap; octetIndex++)
		Tim->PartialVirtualBitMap[octetIndex] = virtualBitMap[offset + octetIndex];
}

void Update_VirtualBitMap(UINT16 station_id, UINT8 Action)
{
	UINT16 aid = station_id;
	UINT8 aid_octet;
	UINT8 aid_bit;
	if ((aid > 0) && (aid < AID_SIZE))
	{
		/* Get aid position in Virtual Bit Map. */
		aid_octet = (UINT8)(aid >> 3);
		aid_bit = (UINT8)(0x01 << (aid & 0x07));
		if (Action == REMOVE_TIM_BIT)
			virtualBitMap[aid_octet] &= ~aid_bit;
		else
			virtualBitMap[aid_octet] |= aid_bit;
	}
}

void main(void)
{
	struct _tim Tim;
	UINT8 ExampleCase;
	ExampleCase = 3;
	switch (ExampleCase)
	{
	case 1:
		mcast_pending = 0;
		Update_VirtualBitMap(2, ADD_TIM_BIT);
		Update_VirtualBitMap(7, ADD_TIM_BIT);
		break;
	case 2:
		mcast_pending = 1;
		Update_VirtualBitMap(2, ADD_TIM_BIT);
		Update_VirtualBitMap(7, ADD_TIM_BIT);
		Update_VirtualBitMap(22, ADD_TIM_BIT);
		Update_VirtualBitMap(24, ADD_TIM_BIT);
		break;
	case 3:
		mcast_pending = 1;
		Update_VirtualBitMap(24, ADD_TIM_BIT);
		break;
	case 4:
		mcast_pending = 0;
		Update_VirtualBitMap(3, ADD_TIM_BIT);
		Update_VirtualBitMap(37, ADD_TIM_BIT);
		Update_VirtualBitMap(43, ADD_TIM_BIT);
		break;
	case 5:
		mcast_pending = 0;
		Update_VirtualBitMap(35, ADD_TIM_BIT);
		break;
	case 6:
		mcast_pending = 0;
		Update_VirtualBitMap(43, ADD_TIM_BIT);
		break;
	case 7:
		mcast_pending = 0;
		Update_VirtualBitMap(35, ADD_TIM_BIT);
		Update_VirtualBitMap(35, REMOVE_TIM_BIT);
		break;
	case 8:
		mcast_pending = 1;
		Update_VirtualBitMap(13, ADD_TIM_BIT);
		Update_VirtualBitMap(43, ADD_TIM_BIT);
		Update_VirtualBitMap(63, ADD_TIM_BIT);
		Update_VirtualBitMap(73, ADD_TIM_BIT);
		break;
	case 9:
		mcast_pending = 1;
		Update_VirtualBitMap(2007, ADD_TIM_BIT);
		break;
	default:
		break;
	}
	Build_TIM(&Tim);
	printf("Element_id = %d.\n", Tim.Element_id);
	printf("IELength = %d.\n", Tim.IELength);
	printf("DtimCount = %d.\n", Tim.DtimCount);
	printf("DtimPeriod = %d.\n", Tim.DtimPeriod);
	printf("BitMapControl = 0x%02X\n", Tim.BitMapControl);
	if (Tim.IELength - TIM_BASE_SIZE > 0)
	{
		int octetIndex;
		for (octetIndex = 0; octetIndex < Tim.IELength - TIM_BASE_SIZE; octetIndex++)
			printf("PartialVirtualBitMap [%d] = 0x%02X\n", octetIndex, Tim.PartialVirtualBitMap
				[octetIndex]);
	}
}

参考

802.11-2007.pdf Annex L

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值