Beispiel #1
0
    def configure(self, base=None, nsuccess=None, nfailure=None, timeout=None, **kwargs):
        """Configure rate adaptation parameters.

        :param base: Base rate used to initialize `RateAdapt` component [default=0].
        :param nsuccess: Threshold for number of consecutive ACKs that must be
                         received prior to increasing the data rate.
        :param nfailure: Threshold for number of consecutive ACK failures that
                         will trigger a decrease in the data rate.
        :param timeout: Timeout that can automatically trigger
        """
        DCF.configure(self, **kwargs)
        if base is None: base = 0
        if nsuccess is None: nsuccess = ARF_NSUCCESS
        if nfailure is None: nfailure = ARF_NFAILURE
        if timeout  is None: timeout  = ARF_TIMEOUT
        ra = self.newchild("ra", RateAdapt, base=base, tracename=self.tracename+".RA")
        ra.set_rate(self.broadcast) # use default base rate for broadcast
        # create FSM to manage ARF
        fsm = self.newchild("manager", FSM, tracename=self.tracename+".MGR")
        fsm.goto(self.MGR)
        # set other parameters
        self.nsuccess = nsuccess
        self.nfailure = nfailure
        self.timeout  = timeout
        self.ackcount = {}
        self.arftimer = {}
        self.probation = {}
Beispiel #2
0
 def log_recv(self, p, *args, **kwargs):
     """Updated to print `RAI` parameters."""
     if ANNO.supported(p):
         if p.haslayer(RAI):
             kwargs['rai-rate'] = p[RAI].rate
             kwargs['rai-length'] = p[RAI].length
         if p.hasanno('phy-rate'):
             kwargs['phy-rate'] = p.getanno('phy-rate')
     DCF.log_recv(self, p, *args, **kwargs)
Beispiel #3
0
 def send_data(self, data):
     """Additional processing for outgoing DATA."""
     DCF.send_data(self, data)
     dst  = data.addr1
     rate = self.ra.get_rate(dst)
     # allow fixed rate for broadcast packets
     fixedrate = data.hasanno('phy-fixed-rate')
     if (data.addr1==self.broadcast) and fixedrate:
         rate = data.getanno('phy-fixed-rate')
     data.setanno('phy-rate', rate)
Beispiel #4
0
 def retry(self, *args, **kwargs):
     """Overloaded to manage dropped ACKs."""
     rc = self.retrycount
     DCF.retry(self, *args, **kwargs)
     # Actual retry?
     if (self.retrycount>rc) and self.isdot11data(self.datatosend):
         # retry count was increased -> dropped ACK
         data = self.get_dot11data(self.datatosend)
         dst, src  = data.addr1, data.addr2
         #self.log("DROPACK", dst=dst, src=src)
         self.dropack.signal(dst)
Beispiel #5
0
 def recv_ack(self, ack):
     """Additional processing for incoming ACK."""
     DCF.recv_ack(self, ack)
     # Expecting ACK?
     if self.isdot11data(self.datatosend):
         data = self.get_dot11data(self.datatosend)
         dst, src = data.addr1, data.addr2
         # ACK for me? -> received ACK
         if (src==ack.addr1):
             #self.log("RECVACK", ack, dst=dst, src=src)
             self.recvack.signal(dst)
Beispiel #6
0
 def send_rts(self, rts, data):
     """Additional processing for outgoing RTS."""
     DCF.send_rts(self, rts, data)
     # get rate and length information
     plen = len(data)
     dst, src = data.addr1, data.addr2
     rate = self.ra.get_rate(dst)
     data.setanno('phy-rate', rate)
     # copy info to RTS/RAI
     rai = rts[RAI]
     rai.rate = rate
     rai.length = plen
Beispiel #7
0
    def configure(self, base=None, thresh=None, **kwargs):
        """Configure rate adaptation parameters.

        :param base: Base rate used to initialize `RateAdapt` component [default=0].
        :param thresh: Dictionary containing minimum SNR threshold corresponding
                       to rate specific index [default=`RBAR_THRESHOLD`].
        """
        DCF.configure(self, **kwargs)
        if base is None: base = 0
        if thresh is None: thresh = RBAR_THRESHOLD
        ra = self.newchild("ra", RateAdapt, base=base, tracename=self.tracename+".RA")
        ra.set_rate(self.broadcast) # use default base rate for broadcast
        self.thresh = thresh
Beispiel #8
0
 def dot11data(self, *args, **kwargs):
     """Overloaded to add 'phy-rate' annotation to new packet."""
     p = DCF.dot11data(self, *args, **kwargs)
     dst = p.addr1
     rate = self.ra.get_rate(dst)
     p.setanno('phy-rate', rate)
     return p
Beispiel #9
0
 def get_dot11data(self, p):
     """Overloaded to extract DATA or RSH."""
     isrsh = self.isdot11rsh(p)
     if isrsh:
         return self.get_dot11rsh(p)
     else:
         return DCF.get_dot11data(self, p)
Beispiel #10
0
    def ctsnav(self, rts):
        """Overloaded to add RSH to NAV and apply rate adaptation..

        :param rts: RTS packet.
        :return: Integer; representing NAV value.

        This method uses `DCF.ctsnav()`, `calcrate()`, and `duration()` to
        calculate the new value of the CTS NAV.
        """
        ctsnav = DCF.ctsnav(self, rts)
        errmsg = "[RBAR]: Invalid RTS! No RAI found in ctsnav()!"
        assert rts.haslayer(RAI), errmsg
        errmsg = "[RBAR]: Cannot find 'phy-sinr' annotation in ctsnav()!"
        assert rts.hasanno('phy-sinr'), errmsg
        # calculate new rate from SINR
        sinr = rts.getanno('phy-sinr')
        newrate = self.calcrate(sinr)
        # extract info from RTS+RAI
        rai = rts[RAI]
        oldrate, length = rai.rate, rai.length
        # recompute NAV using length and new rate
        dold = self.duration(length, oldrate)
        dnew = self.duration(length, newrate)
        nav = ctsnav - int(dold*1e6) + int(dnew*1e6)
        return nav
Beispiel #11
0
 def rtsnav(self, p, *args, **kwargs):
     """Overloaded to add RSH to NAV."""
     nav = DCF.rtsnav(self, p, *args, **kwargs)
     # add RSH + SIFS
     d = self.sifs + self.rshduration
     nav += int(d*1e6)
     return nav
Beispiel #12
0
 def TXRSH(self, fsm):
     """TXRSH state; overloaded to send RSH prior to DATA."""
     assert DCF.isdot11data(self, self.datatosend), \
             "[RBAR]: Cannot determine 'datatosend' in TXUCAST!"
     assert not (self.datatosend.addr1==self.broadcast), \
             "[RBAR]: Cannot send broadcast 'datatosend' in TXUCAST!"
     # update rate annotation
     data = self.get_dot11data(self.datatosend)
     dst, src = data.addr1, data.addr2
     rate = self.ra.get_rate(dst)
     data.setanno('phy-rate', rate)
     if not self.usecsma:
         # send RSH before sending DATA
         rsh = self.dot11rsh(addr1=dst, addr2=src)
         self.send_rsh(rsh, self.datatosend)
         # recalculate NAV from new rate information
         nav = self.rshnav(self.datatosend)
         rsh.ID = nav
         pkt = crcupdate(rsh)
         # send and hold for duration
         rate, length = pkt[RAI].rate, pkt[RAI].length
         self.log("RSH", pkt, nav=nav, rate=rate, length=length)
         duration = self.duration(pkt)
         self.log_send(pkt, nav=nav)
         yield self.TXD.send(fsm, [pkt])
         yield hold, fsm, duration
         # pause for SIFS before continuing
         yield hold, fsm, self.sifs
     # go to DCF.TXUCAST state
     OLDSTATE = lambda *args, **kwargs: DCF.TXUCAST(self, *args, **kwargs)
     yield fsm.goto(OLDSTATE)
Beispiel #13
0
 def __init__(self, usecsma=True, **kwargs):
     """Constructor."""
     # create ARF parameters
     self.nsuccess = None
     self.nfailure = None
     self.timeout  = None
     self.ackcount = {}
     self.arftimer = {}
     self.probation = {}
     self._rates = None
     # create ARF events
     self.dropack = SimEvent()
     self.recvack = SimEvent()
     DCF.__init__(self, usecsma=usecsma, **kwargs)
     # update event names
     self.dropack.name = "%s%s"%(self.name, ".dropack")
     self.recvack.name = "%s%s"%(self.name, ".recvack")
Beispiel #14
0
 def dot11cts(self, *args, **kwargs):
     """Overloaded to add 'phy-rate' annotation to new packet."""
     rargs = {}
     for s in ['rate', 'length']:
         if s in kwargs:
             rargs[s] = kwargs[s]
             del kwargs[s]
     # create CTS + RAI payload
     p = DCF.dot11cts(self, *args, **kwargs)/RAI(**rargs)
     p.setanno('phy-rate', self.base)
     return p
Beispiel #15
0
    def send_cts(self, cts, rts):
        """Additional processing for outgoing CTS.

        :param cts: Outgoing CTS packet.
        :param rts: Received RTS packet.

        This method uses the 'phy-sinr' annotation to apply the rate adaptation
        algorithm used by `RBAR`.
        """
        DCF.send_cts(self, cts, rts)
        errmsg = "[RBAR]: Invalid RTS! No RAI found in send_cts()!"
        assert rts.haslayer(RAI), errmsg
        errmsg = "[RBAR]: Invalid CTS! No RAI found in send_cts()!"
        assert cts.haslayer(RAI), errmsg
        errmsg = "[RBAR]: Cannot find 'phy-sinr' annotation in send_cts()!"
        assert rts.hasanno('phy-sinr'), errmsg
        # extract info from RTS+RAI
        sinr = rts.getanno('phy-sinr')
        newrate = self.calcrate(sinr)
        cts[RAI].rate = newrate
        cts[RAI].length = rts[RAI].length
Beispiel #16
0
    def rshnav(self, data, *args, **kwargs):
        """Calculate NAV value for RSH.

        :param data: DATA packet.
        :param args: Arguments passed on to `DCF.rtsnav()`.
        :param kwargs: Keywords passed on to `DCF.rtsnav()`.
        :return: Integer; representing NAV value.

        This method computes the RSH NAV as follows:

            NAV = SIFS + DATA + SIFS + ACK

        :note: This method uses `DCF.rtsnav()` to calculate the new NAV value.
        """
        # Use regular RTS NAV (i.e. from DCF) to compute new NAV value
        rtsnav = DCF.rtsnav(self, data, *args, **kwargs)
        d = self.sifs + self.ctsduration
        nav = rtsnav - int(d*1e6)
        return nav
Beispiel #17
0
 def log_recv(self, p, *args, **kwargs):
     """Updated to print `ARF` related parameters."""
     if p.hasanno('phy-rate'):
         kwargs['phy-rate'] = p.getanno('phy-rate')
     DCF.log_recv(self, p, *args, **kwargs)
Beispiel #18
0
 def send_data(self, data):
     """Additional processing for outgoing DATA."""
     DCF.send_data(self, data)
     dst  = data.addr1
     rate = self.ra.get_rate(dst)
     data.setanno('phy-rate', rate)
Beispiel #19
0
 def isdot11data(self, p):
     """Overloaded to check for DATA or RSH."""
     isdata = DCF.isdot11data(self, p)
     isrsh = self.isdot11rsh(p)
     return (isdata or isrsh)
Beispiel #20
0
 def dot11ack(self, *args, **kwargs):
     """Overloaded to add 'phy-rate' annotation to new packet."""
     p = DCF.dot11ack(self, *args, **kwargs)
     p.setanno('phy-rate', self.base)
     return p
Beispiel #21
0
 def __init__(self, usecsma=None, **kwargs):
     """Constructor."""
     self.thresh = None
     self._rshduration = None
     DCF.__init__(self, usecsma=False, **kwargs)