• NS 802.11函数分析(一)


     recv函数有两个作用,不仅是接收其他节点发送的包,而且当节点接收到其他包的时候也会调用recv()

    首先给出NS2中recv的源码,和一些注释:

     1 void
     2 Mac802_11::recv(Packet *p, Handler *h)
     3 {
     4     struct hdr_cmn *hdr = HDR_CMN(p);
     5     /*
     6      * Sanity Check
     7      */
     8     assert(initialized());
     9 
    10     /*
    11      *  Handle outgoing packets.
    12      */
    13     if(hdr->direction() == hdr_cmn::DOWN) {//向下传输,也就是节点要向外发送,故调用recv()
    14                 send(p, h);
    15         
    16 return; 17 } 18 /* 19 * Handle incoming packets. 20 * 21 * We just received the 1st bit of a packet on the network 22 * interface. 23 * 24 */ 25 26 /* 27 * If the interface is currently in transmit mode, then 28 * it probably won't even see this packet. However, the 29 * "air" around me is BUSY so I need to let the packet 30 * proceed. Just set the error flag in the common header 31 * to that the packet gets thrown away. 32 */ 33 if(tx_active_ && hdr->error() == 0) {//如果当前正在发送的话则标记为错误,这个数据包会在后面的函数中被处理掉 34 hdr->error() = 1; 35 } 36 37 if(rx_state_ == MAC_IDLE) {//如果当前空闲则设置为接收态 38 setRxState(MAC_RECV); 39 pktRx_ = p; 40 /* 41 * Schedule the reception of this packet, in 42 * txtime seconds. 43 */ 44 if (mhProbe_.busy() && OnMinChannelTime) { 45 Recv_Busy_ = 1; // Receiver busy indication for Probe Timer 46 } 47 48
    49 mhRecv_.start(txtime(p)); 50 } else { 51 /* 52 * If the power of the incoming packet is smaller than the 53 * power of the packet currently being received by at least 54 * the capture threshold, then we ignore the new packet. 55 */ 56 if(pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh) {//有冲突发生时,如果新到的包功率比较小,信噪比在阀值以下的时候调用capture函数,主要作用是 57 capture(p); 58 } else {//冲突比较大的时候需要调用冲突函数 59 collision(p); 60 } 61 }

       总结一下recv函数的工作流程主要是以下一些阶段:

      1、判断这个包是要发出去的还是收到的,发出去的直接调用send函数就行;

      2、判断MAC的状态,如果是发送态就直接将这个包标记为错误(这个错误会在后面处理),如果是空闲状态,则这个时候可以正常接收数据包,将MAC状态转换成MAC_RECV状态然后保存定时器(定时器的作用是NS2模拟发包过程,当定时器为零才发送完成)

      3、如果MAC不是空闲,我们正在接收其他的包,那么我们需要判断这时新到的包是否会影响到原来正在接收的,也就是计算信噪比与阀值比较,当在阀值以下的时候我们忽略这个包(调用capture),否则产生冲突。

    但是这两个函数也不是十分简单的。首先看capture:

     1 void
     2 Mac802_11::capture(Packet *p)
     3 {
     4     /*
     5      * Update the NAV so that this does not screw
     6      * up carrier sense.
     7      */    
     8     set_nav(usec(phymib_.getEIFS() + txtime(p)));
     9     Packet::free(p);
    10 }

        这段代码的作用是当新到达的包不会对原来的接收造成影响的时候,将这个包作为一个多余的信息丢掉,即free。但是还有一个设置NAV的值为EIFS+这个数据包传输时间,关于这一点我的理解是:假设这个节点顺利完成了当前的接收任务,如果说干扰包的发送还是没有完成的话,必然会再次收到它的信号,但是这个信号必然是无效的,所以直接设置NAV可以避开这个问题

    再看collision:

     1 void
     2 Mac802_11::collision(Packet *p)
     3 {
     4     switch(rx_state_) {
     5     case MAC_RECV:
     6         setRxState(MAC_COLL);
     7         /* fall through */
     8     case MAC_COLL:
     9         assert(pktRx_);
    10         assert(mhRecv_.busy());
    11         /*
    12          *  Since a collision has occurred, figure out
    13          *  which packet that caused the collision will
    14          *  "last" the longest.  Make this packet,
    15          *  pktRx_ and reset the Recv Timer if necessary.
    16          */
    17         if(txtime(p) > mhRecv_.expire()) {
    18             mhRecv_.stop();
    19             discard(pktRx_, DROP_MAC_COLLISION);
    20             pktRx_ = p;
    21             mhRecv_.start(txtime(pktRx_));
    22         }
    23         else {
    24             discard(p, DROP_MAC_COLLISION);
    25         }
    26         break;
    27     default:
    28         assert(0);
    29     }
    30

    这一段代码主要是完成冲突的处理:

    1、判断如果是正常接收状态,到这应该应经是冲突发生了,所以我们要改变MAC的状态。

    2、在冲突状态下,他这采取了选择接收结束时间按比较晚的那个包(但是这个包最终也会因为冲突发生被丢弃),至于原因感觉跟上面差不多既然冲突发生了,即使后来可以接收到一部分正确的包,但是意义也不大,所以直接用接收一个时间较长的把这段跳过去。

      这就是recv的大概过程了,牵涉的其他细节由于暂时没有用到就没有深究了。我理解不对的地方欢迎指正。

    如果你觉得内容对你有帮助,请点个赞

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
  • 相关阅读:
    NameError: name 'picamera' is not defined
    Linux 键盘输入#的时候变成£
    AngularJS之高级Route【三】(八)
    AngularJS之中级Route【二】(七)
    AngularJS之初级Route【一】(六)
    AngularJS之Dependency Injection(五)
    AngularJS之Service(四)
    AngularJS之Filter(二)
    AngularJS之Scope及Controller(一)
    JQuery利用sort对DOM元素进行排序
  • 原文地址:https://www.cnblogs.com/MrLJC/p/3423645.html
Copyright © 2020-2023  润新知