• 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 
    #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]);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141

    参考

    802.11-2007.pdf Annex L

  • 相关阅读:
    Java 8被抛弃,甲骨文份额萎缩超一半,2022年Java生态报告出炉
    J1_搭建Web环境,初识JSP
    开放智慧,助力学习——电大搜题,打开学无止境的新篇章
    前沿研究|16s+宏基因组binning揭示大型藻类附生微生物群落核心组成
    抖音矩阵系统-60+自媒体平台一键发布-短视频获客系统
    线性代数学习笔记4-1:线性方程组的数学和几何意义、零空间/解空间/核
    Tensorflow2.0:CNN、ResNet实现MNIST分类识别
    身份证实名核验,身份证实名认证,身份证二要素实名认证,身份证实名校验,身份证一致性实名认证
    2022.9.17-----leetcode.1624
    低代码平台上的出入库管理
  • 原文地址:https://blog.csdn.net/m0_38059875/article/details/128052569