13

802.11协议精读38:再论Block-ACK(802.11e)

 3 years ago
source link: https://zhuanlan.zhihu.com/p/398496527
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

802.11协议精读38:再论Block-ACK(802.11e)

Wi-Fi话题下的优秀答主

序言

关于Block ACK的内容,前面一篇《802.11协议精读26:802.11e(TXOP,Block_ACK)》虽然把机理大致都说明了,但是有些细节还需要补完,特别是在帧结构方面的问题。

Block ACK的细节主要麻烦的点在于版本的演进,我们目前实际采用的大多都是在802.11n时候定义的Block ACK结构,但是最初802.11e时候的很多细节实际上和802.11n还是有差别的。然后到后来的802.11ac,aa(GCR),ax之类,其实关于这一点还有更多的改动的地方。目前协议精读仍然没开始写802.11n的内容,主体还是放在802.11e的结构上,所以核心点还是围绕802.11e而言,本文会捎带提及一些802.11n中block ACK的内容,到以后写n和帧聚合的时候再详细阐述。另外在802.11n以后block ack还有演进,比如Multi-STA Block ACK之类,这个给到n以后版本对应位置的时候再补充了。

本文仍然是偏细节类型的,而且很多都是个人理解而言,由于802.11e没有单独的实现版本,没法抓包验证,所以理解不对的还请见谅。另外一点就是,802.11协议的掌握,如果偏细的学习的话,还是建议逐个版本演进的来,从我目前翻过的草案和协议版本来看,其实协议本身制定过程就是挺慢的逐个点推进的,每一个点其实说起来都挺细,有一些内容。所以如果纯粹当作功能形式的学习的话,非常容易抓不住重点,感觉整个机制还是挺复杂的,然而实际把主轴抓住以后,整体还是比较容易想的通的。其实要说简单点,就是核心思路很简单,然后后面就是根据场景,根据需求不断完善而已。最后,这一篇是需要《802.11协议精读26:802.11e(TXOP,Block_ACK)》这里基础的,对于这一块不熟悉的可以先看这篇。

802.11e的Block ACK

802.11e中首先是定义了Block ACK的大框架,其实就是ADDBA,DATA/BAR/BA(多轮),DELBA这一套处理机制。

v2-474fe8ca8c3c119b25750d512e8e70cd_720w.jpg

如同协议中描述的,分别就是(a) Setup,(b) Data&Block Ack,(c) Tear Down这三个组成部分。该图中还需要关注到,这里特意将Data & Block Ack过程框起来,强调了multiple times,这代表了一个ADDBA的会话,其实可以较长时间存在,并且维护多次的数据帧传输的。这一点在上一篇里面没有强调,但是很容易造成误解(错误理解成一次传输就需要一次ADDBA会话,正确理解是一次ADDBA会话可以管理多次传输)。

其实以上三个过程里面,我们这里主要关注下Setup的ADDBA,以及Data & Block ACK过程。DELBA没什么特殊性,所以没有什么补充的。

ADDBA过程(强调Block ACK Policy)

在ADDBA过程主要关注的细节是在Block Ack Policy上面。我们在上一篇说过,802.11e中定义了两种Block Ack的反馈方式,(1)立即反馈,(2)延迟反馈。但是究竟在当前的传输过程中用哪一种Block ACK反馈方式呢?

在802.11e中就存在限制,也就是Block ACK和ADDBA所限定下来的会话实际上是绑定的。换言之,在802.11e中,需要一开始建立ADDBA的时候进行过一次Block ACK Policy的设置。

在802.11e中,Block ACK Policy的设置是通过ADDBA中的Block Ack Parameter字段来设置的,该字段就是ADDBA action帧(就单独截一个ADDBA Request示意下,reponse里面一样有该字段)中的一个部分

802.11e

同样这里我们还可以注意到802.11e里面包含两个属性,TID和Buffer Size,这里需要注意,Block Ack是和AC绑定起来的,所以建立会话的时候需要指定TID。另外,由于存在多帧重组之类的问题(这里的细节是关于什么时候MAC帧往上层反馈的问题),所以这里还有缓存帧数量的问题,所以存在一个buffer size的设置。

802.11n

到802.11n里面,原有的部分还是保留的,但是可以看到在一开始的保留字段里面,修改成了A-MSDU Supported,这就对应到802.11n里面引入的MSDU级别聚合的问题了。

那么回到这里我们所强调的Block ACK Policy。

在802.11e的时候,这个是不能够在会话过程通过BAR调节的,在802.11e里面关于ACK policy的部分,实际上是嵌套在QoS Control字段里面的,在传输过程中,可以根据QoS-Data对应的QoS Control来设置BA的反馈方式。其实这点也比较细节,需要注意一下。

802.11e(QoS Control)

不过在802.11e的BAR帧里面,就没有Ack Policy的字段。

802.11e

而到802.11n之后,我们可以直接通过BAR帧来直接调节ACK policy。

802.11n

这里对比一下就可以很明显的看出来,在802.11e的时候BAR Control实际上是大量留白的,而在802.11n的时候,为了更灵活调节Block ACK Policy,所以能够将其嵌入到BAR里面。

另外802.11n这里BAR Ack Policy仅仅1个bit,其功能具体对应如下,其实还是选择立即反馈或者延迟反馈的

那么这里我们要理解几点内容,

  • 1)按照802.11协议本身的机理,BAR ACK policy(Block ACK Policy)这个其实算是一个会话的属性,通常这种属性的修改还是应该通过action帧的交互,用管理帧在会话层面进行修改。但是802.11本身就具有很强的best-effort特征,笔者理解就是需求到了,就不用拘泥默认规则,就需要放到会话里面去,其他的协议,比如3GPP的就非常少见到这种方式。
  • 2)其实按照道理,BAR ACK policy放在BAR Control里面其实更合理一些,放到BAR Control,其实就是放在BAR帧里面,其实就代表了BAR ACK policy应该跟着一次传输走,而不是整个BA会话。当时802.11e选择跟着会话走,一个原因应该还是基于TXOP会话当时比较固定,从这个角度而言,把BAR ACK policy和BA会话绑定实现起来会更加的简单。但是后面协议关于TXOP的使用,以及帧聚合等等的扩展,那么代表了在一次BA过程里面,每一次DATA的传输的情况就有可能不一样,进而反馈策略应该跟着每一次传输走,而不是跟着整个会话。
  • 3)不要忽略ADDBA过程。在802.11e以前,整个802.11结构里面都没有类似会话结构的出现,或者说,只有安全秘钥这个层面才有一个会话,其他的PHY,MAC层面其实没有类似于会话的机制,典型的比如说Data Rate的调节,就没有会话协商的过程。因此,普遍大家理解Block ACK的过程中,会直接将ACK和Block ACK进行对比,进而就主要关注BAR,BA和原来ACK帧的差别,并且在细节上能够将BAR ACK policy的这些都给对上(即802.11n版本的时候),从而实现了一种理解。不过整个过程是忽略了ADDBA和DELBA过程的,以及数据传输时候对应的QoS Control部分,进而其实没有把握住这是基于一个会话的机制。而如果直接从802.11e入手的话,整个机制的连贯就少不了ADDBA(尤其体现在ACK policy上面),所以这点是需要注意的。另外其实在802.11n里面,其延迟反馈和立即反馈还和802.11e的有点区别,其新增的HT-延迟和HT-立即反馈。这一点写n的时候再进行补充。

其余ADDBA的过程我目前理解没什么需要补充的了,下面关于Data & Block ACK的过程。

Block ACK过程(802.11e)

这一部分第一点是在前面强调的,也就是一个BA会话可以管理多次的Block ACK,也就是多次的传输过程。那么第二点我们主要关注一下Block ACK的帧结构。

在802.11e的时候,Block ACK Request(BAR)结构如下

802.11e

可以看到这个其实和一个标准的控制帧区别不大,就多了两个字段。一个是BAR Control,一个是Block Ack Starting Sequence Control。

802.11e

BAR Control前面也打开过,里面其实就是一个TID,代表了这个BAR帧是针对哪一个AC,也就是优先级类型进行请求的。然后剩下来就是在BAR里面标明所请求的聚合帧,其首个MSDU其对应的sequence号是多少,节点就依照这个sequence号进行反馈。

802.11e

另外需要注意的还有Block Ack Starting Sequence Control字段。这里需要注意802.11的Sequence Control Field的机理,也就是顺序控制的问题。802.11的sequence控制的部分其实是有frag number和sequence number两者结合在一起使用的,这个设计早期是因为无线传输速率较慢,如果单帧较长时间的传输,有可能会被干扰,以及传输长帧时所带来的冲突开销较大,所以这里需要做一个分片。那么为了分片对方能够重组,所以需要构成分片号(frag number)和序列号(sequence number这两个机制)。协议中有强调了下,The Fragment Number subfield is always set to 0,其实也就是分片机制和BA机制大部分情况下不会复用。

这里就直接截的权威指南里面的图了。我们前面这里说的BA里面的Bitmap实际上是针对MPDU的,但是实际上sequence号不是跟着MPDU走的,而是跟着MSDU走的。所以会存在多个MPDU使用相同的MSDU序列号(其通过frag number来区分)。所以在BAR请求的是,为了指向特定的MPDU,不仅仅要指向其特定的MSDU序列号,还需要标识frag number。

Remark:其实这里还有一个细节可以参悟下,就是原始协议设计的时候,就把sequence number放在低位,把frag number放在高位。其实按照分层细分的道理而言,应该反过来放。但是协议设计的时候是正着放的,从笔者观点上来看,协议设计之初其实就有人意识到,随着物理层速率传输越来越快,frag分片的机制会被慢慢淘汰掉,所以放在高位以后就不会影响序列号的连续性,即当MPDU等价于MSDU的时候,后面的sequence号还是连续的。但是如果把sequence number放在高位,把frag number放在低位,那么就会出现非连续的情况了,也就是当不使用frag number的时候,那几个位实际上空置,但是从二进制序列解析的层面上,导致整个序列号,也就是seq-ctl这个字段非连续了。802.11协议初始版本实际上这样的细节有很多,也因为这样打下了协议比较厚实灵活的基础,毕竟从协议组初创90年左右开始,到协议第一个版本97年,实际经过了7年的打磨,很多地方其实细想都还是有很多东西的。

前面说完BAR帧,下面关注BA帧,那么在802.11e中反馈的BA帧的结构如下

802.11e

其实该帧结构也比较简单,相比标准控制帧,多了BA Control,Block Ack Starting Sequence Control,以及Block Ack Bitmap字段。BA Control和Block Ack Starting Sequence Control,在BA中和BAR的其实一样。BA Control核心就是指明一个TID。Block Ack Starting Sequence Control字段,其指示了BA反馈的时候,起始反馈对应的MSDU序列号是多少。BAR请求的时候有一个起始序列号,这里反馈也有一个,实际上也是为了保证反馈的时候能和起始的对上,增加鲁棒性的。然后就是一个128 Bytes的Block Ack Bitmap,这里挺长的,128 Bytes,那么实际最高能够对应1024个MPDU,写1代表成功接收,写0代表没有接收到。

其实原文这里实际上是大致写明为啥米设置128 bytes这么长的

主要是128 bytes可以表示1024个MPDU或者最高64个MSDU,因为在802.11的版本中其实已经支持分片,一个MSDU可以通过分片形成多个MPDU,这里相当于假设一个MSDU最多可以分成16片了。最后一句话,关于未使用分片的MSDU,对应的bitmap位置设置成0。这里其实是对应前面说的分片机制和BA机制不会复用而言的,主要是解决如果分片和BA机制复用了以后怎么办。

由于在BA反馈的时候,仅仅只标注了起始的sequence号以及对应分片。但是由于bitmap仅仅只能够在一种配置属性下表示,换言之,初始的sequence号和分片号或者分片结构,其实就已经把BA的bitmap给划分成多个块了,其实每一个块就对应一个MSDU,所以这里才说了一个BA最多支持64个MSDU。比如我们就按照MSDU最大划分的角度来理解,1号帧是采用了16分片,那么bitmap上面每一位都针对一个frag number,但是如果2号帧没有采用frag number,但是由于Bitmap的默认解析结构已经,所以2号帧实际上Bitmap的空间也占了16位,那么这些没有使用的bitmap的位置其对应也置成0。从而和协议这里最后一句话对应上。

所以这里再次注意,BA本身的目的是最多反馈64个MSDU,所以如果把分片整个机制干掉,也就是MSDU直接等价MPDU,那么这里bitmap仅仅需要8个Bytes即可。所以在802.11n里面就存在一种压缩bitmap,即compress BA的机制,8 Bytes其实也就是对应最高64bits bitmap的大小。

那么下面我们开始对比802.11n里面的BAR和BA机制。

Block ACK过程(802.11n)

首先还是先看BAR帧,从帧结构整体而言,还是有BAR Control,但是原始的Start sequence更新成了一个变长度的BAR Information字段,代表这一块有功能扩展了。

802.11n

BAR Control其实前面也打开来过,具体如下

802.11n

BAR Ack Policy前面已经说过了,这里就不重复了。这里我们看下另外三个不一样的字段,即Multi-TID,Compressed Bitmap以及TID_Info。在802.11e里面的BAR Control字段里面,其实就是指定了一种TID而已。在802.11n的时候,由于BA的种类增加了,所以在BAR里面也添加了请求对应的标志位。

在802.11n中,新增了两种BA,即compressed BA以及Mutli-TID BA。前者是可以传输更小的BA,具体就是bitmap大小更小。后者即是可以在一个BAR帧中,请求多个不同AC类型的BA,从而节约所需要的BAR帧,并且降低反复发送所带来的延迟。

结合Multi-TID位和Compressed Bitmap位,我们这里可以确定具体的BA机制

802.11n

至于TID Info字段,该字段B12-B15的位置其实就是对应原来BAR Control中的TID字段,所以本质还是指定TID的,只不过现在名字变成了TID Info。如果是basic block ack或者compressed block ack的话,那么TID Info实际上还是值得是对应的TID号。并且在BAR Control之后的BAR Information的内容的话,其实就是之前的Block Ack Starting Sequence Control字段。换言之,还是通过TID Info指定特定的AC,并且通过开始的序列号,定位到具体请求BA的MPDU上。

不过由于802.11n中还引入了Multi-TID结构,所以这里还存在点区别。在Multi-TID的时候,其实在BAR Control的TID Info需要改变下。TID Info的信息实际上需要放到BAR Information字段里面。

802.11n

当Multi-TID的BAR的时候,实际上就是指定一个TID,然后指定其对应的starting sequence number,从而进行请求。有多少个需要请求的AC,那么就有多少个独立存在的<TID,Starting sequence number>的结构。通过这样就可以首先一个BAR请求多个AC对应的BA了。

那么下面开始关注BA帧结构,从整体结构上面而言,就是将原始直接反馈的start schedule number号和Bitmao封装进了BA Information里面。

802.11n

在802.11n的时候,BA机制包含三种,即传统的BA,Compressed BA,以及Mutli-TID BA。

BA Control的部分其实和BAR Control是一样的,而BA Information的部分主要体现在bitmap大小上的差别,传统的就是Bitmap部分占128个字节,代表最高64个MSDU。在Compressed BA中,bitmap占8个字节,有效降低传输开销,提升了效率。具体如下图

802.11n

这里对于compressed的理解,一方面体现是在bitmap大小上面变更小了,另外一方面其实就是默认把fragment number部分直接置0了。

802.11n

另外一方面,可以对比下协议上面部分的描述(即compressed和normal模式下的BA的描述),其实这个bitmap对应的本质还是64个MSDU,只不过normal模式下面允许fragment(分片),所以为了包含分片所需要的扩展空间,增加到了128 Bytes,而在compressed模式下,其实就是把分片给禁了,从而缩减到了8 Bytes。

compressed BA应该是目前实际中最常用的BA类型,那么除了compressed BA以外,802.11n里面还增加了Multi-TID BA。这个我们可以简单理解成,一个BA里面可以包含多个不同TID的BA。

802.11n

其实在抓包里面就体现出这样类似的

其实就是每一个TID单独列出来,然后分别表示其对应的信息和Bitmap。这里每一个TID里面也都是采用8个Bytes的bitmap。其实就是这一点区别。

那么在802.11n以后block ack还有啥米演进呢。。。这个详细到以后写到这个时候再整理,这里简单提一下。比如引入的Extend Compressed BA,其实就是在帧结构最后加上了一个RBUFCAP字段,比如抓包看起来是这样

协议里面结构这样

RBUFCAP的缩写应该是Receiver Buffer Capacity,这里1个bit,实际上就代表了对方还能不能有没有接收缓存。

还有Multi-STA BA,其实就是在Multi-TID的基础上,还将节点的AID进行封装,所以可以对多个节点进行BA反馈。另外还有GCR的case,这个是和802.11aa有关了。以后分别写到这些扩展的时候,再提这一点。

Block ACK过程(Duration)

另外关于BAR帧中的duration字段,这里另外还发现了一个实际抓包里面的情况,不过还没有广泛验证。就是这里发现在BAR帧对应的duration字段里面,这一块Duration设置的值都很大。而实际反馈的BA帧的length实际上只有32 Bytes,其实都是compress BA帧了。

按照协议而言,这一块的Duration时间应该覆盖到BA帧即可,如下

所以不禁让我怀疑,这里BAR设置计算的时候,其实是默认按照802.11e时期的BAR帧结构来算的,这里目前3.0版本的wireshark感觉没有把BAR Control里面的compressed bitmap这个标志位给解析出来(BA里面解析了),所以不知道BAR帧这个特点没有丢给对方。如果这里不是没解析,而就是没设置的话,那么这里其实就能够解释为BAR请求的时候,还是按照802.11e时期默认的BAR请求的,那么对应其反馈的bitmap就有128 Bytes长,所以duration时间就设置比较长了。目前这个问题不知道是不是广泛的问题,仅仅我看了一个老点的抓包发现这个case。

以上就是基本是把block ack一些细节补完了一下。

本文为原创文章,如需转载须注明出处和原文链接。

欢迎大家关注我们的微信公众号:无线技术大讲堂,请搜索公众号(must_wireless)。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK