Ejemplo n.º 1
0
def apply_rate(cur_time):
    global currRate, npkts, nsuccess, NBYTES, NRETRIES
    remove_stale_results(cur_time)
    
    #"Increment the number of packets sent over the link"
    npkts += 1
    
    #"If no packets have been successfully acknowledged, return the
    # highest bit-rate that has not had 4 successive failures."
    if nsuccess == 0:
        for i, r in sorted(rates.items(), reverse=True):
            if r.succFails < MAXFAILS:
                currRate = r.rate
                return [(ieee80211_to_idx(currRate), NRETRIES)]

    # Every 10 packets, select a random non-failing bit rate w/ better avg tx
    #"If the number of packets sent over the link is a multiple of ten,"
    if (nsuccess != 0) and (npkts%10 == 0):
        #"select a random bit-rate from the bit-rates"
        cavgTX = rates[currRate].avgTX

        #" that have not failed four successive times and that
        #have a minimum packet transmission time lower than the
        #current bit-rate’s average transmission time."
        eligible = [r for i, r in rates.items()
                    if r.losslessTX < cavgTX and r.succFails < MAXFAILS]

        if len(eligible) > 0:
            sampleRate = choice(eligible).rate #select random rate from eligible
            return [(ieee80211_to_idx(sampleRate), NRETRIES)]

    #"Otherwise, send packet at the bit-rate that has the lowest avg transmission time"
    # Trusts that currRate is properly maintained to be lowest avgTX
    return [(ieee80211_to_idx(currRate), NRETRIES)]
Ejemplo n.º 2
0
def apply_rate(cur_time):
    global currRate, npkts, nsuccess, NBYTES, NRETRIES
    remove_stale_results(cur_time)

    #"Increment the number of packets sent over the link"
    npkts += 1

    #"If no packets have been successfully acknowledged, return the
    # highest bit-rate that has not had 4 successive failures."
    if nsuccess == 0:
        rrates = [r[1] for r in sorted(rates.items())]
        rrates.reverse()
        retry = []
        for r in rrates:
            if r.succFails < 4:
                currRate = r.rate
                retry.append((ieee80211_to_idx(currRate), NRETRIES))
        return retry

    # Every 10 packets, select a random non-failing bit rate w/ better avg tx
    #"If the number of packets sent over the link is a multiple of ten,"
    if (nsuccess != 0) and (npkts % 10 == 0):
        #"select a random bit-rate from the bit-rates"
        cavgTX = rates[currRate].avgTX

        #" that have not failed four successive times and that
        #have a minimum packet transmission time lower than the
        #current bit-rate's average transmission time."
        eligible = [
            r for i, r in rates.items()
            if r.losslessTX < cavgTX and r.succFails < 4
        ]

        if len(eligible) > 0:
            sampleRate = choice(
                eligible).rate  #select random rate from eligible
            return [(ieee80211_to_idx(sampleRate), NRETRIES)]

    #"Otherwise, send packet at the bit-rate that has the lowest avg transmission time"
    # Trusts that currRate is properly maintained to be lowest avgTX
    return [(ieee80211_to_idx(currRate), NRETRIES)]
Ejemplo n.º 3
0
import os
import common

RATE=float(os.environ["RATE"]) if "RATE" in os.environ else 1

# Read the rate as a Mbps value and convert it to an index
try:
    IDX = common.ieee80211_to_idx(RATE)
except ValueError:
    opts = [str(rate.dot11_rate / 2) for rate in common.RATES]
    print("Invalid rate.  Options are: {}".format(", ".join(opts)))
    exit()
else:
    print("Running at rate %r Mbps..." % RATE)

def apply_rate(time):
    return [(IDX, 4)] * 4

def process_feedback(status, timestamp, delay, tries):
    pass
Ejemplo n.º 4
0
def bitrate_type(bitrate):
    return common.RATES[ieee80211_to_idx(bitrate)].phy
Ejemplo n.º 5
0
def bitrate_type(bitrate):
    return common.RATES[ieee80211_to_idx(bitrate)].phy
Ejemplo n.º 6
0
def tx_time(rate, length): #rate is Mbps, length in bytes
    return common.tx_time(ieee80211_to_idx(rate), length)
Ejemplo n.º 7
0
def apply_rate(cur_time): #cur_time is in nanoseconds
    global npkts, nsuccess, nlookaround, NBYTES, currRate, NRETRIES, np, nd
    global bestThruput, nextThruput, bestProb, lowestRate, time_last_called

    if cur_time - time_last_called >= 1e8:
        update_stats(cur_time)
        time_last_called = cur_time

    #Minstrel spends a particular percentage of frames, doing "look around" i.e. 
    #randomly trying other rates, to gather statistics. The percentage of 
    #"look around" frames defaults to 10%. The distribution of lookaround frames is
    #also randomized somewhat to avoid any potential "strobing" of lookaround 
    #between similar nodes.
    
    #Try |         Lookaround rate              | Normal rate
    #    | random < best    | random > best     |
    #--------------------------------------------------------------
    # 1  | Best throughput  | Random rate       | Best throughput
    # 2  | Random rate      | Best throughput   | Next best throughput
    # 3  | Best probability | Best probability  | Best probability
    # 4  | Lowest Baserate  | Lowest baserate   | Lowest baserate
    delta = (npkts*.1 - (np + nd/2.0))
    if delta > 0: #random!
        #Analysis of information showed that the system was sampling too hard
        #at some rates. For those rates that never work (54mb, 500m range) 
        #there is no point in sending 10 sample packets (< 6 ms time). Consequently, 
        #for the very very low probability rates, we sample at most twice.
        
        if npkts >= 10000:
            np = 0
            npkts = 0
            nd = 0
        elif delta > len(rates) * 2:
            '''FROM KERNEL COMMENTS:
            /* With multi-rate retry, not every planned sample          
            * attempt actually gets used, due to the way the retry     
            * chain is set up - [max_tp,sample,prob,lowest] for        
            * sample_rate < max_tp.                                    
            *                                                          
            * If there's too much sampling backlog and the link        
            * starts getting worse, minstrel would start bursting      
            * out lots of sampling frames, which would result          
            * in a large throughput loss. */'''
            np += delta  - (len(rates)*2)
            

        random = choice(list(rates))
        while(random == 1): #never sample at lowest rate
            random = choice(list(rates))

        if random < bestThruput:
            chain = [bestThruput, random, bestProb, lowestRate]
            ''' FROM KERNEL:
            /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark        
            * packets that have the sampling rate deferred to the      
            * second MRR stage. Increase the sample counter only       
            * if the deferred sample rate was actually used.           
            * Use the sample_deferred counter to make sure that        
            * the sampling is not done in large bursts */'''
            probe_flag = True
            nd += 1

        else:
            #manages probe counting
            if rates[random].sample_limit != 0:
                np += 1
                if rates[random].sample_limit > 0:
                    rates[random].sample_limit -= 1
            
            chain = [random, bestThruput, bestProb, lowestRate]
    
    else:     #normal
        chain = [bestThruput, nextThruput, bestProb, lowestRate]

    mrr = [(ieee80211_to_idx(rate), rates[rate].adjusted_retry_count)
           for rate in chain]

    return mrr
Ejemplo n.º 8
0
def apply_rate(cur_time):  #cur_time is in nanoseconds
    global npkts, nsuccess, nlookaround, NBYTES, currRate, NRETRIES
    global bestThruput, nextThruput, bestProb, lowestRate, time_last_called

    if cur_time - time_last_called >= 1e8:
        update_stats(cur_time)
        time_last_called = cur_time

    #Minstrel spends a particular percentage of frames, doing "look around" i.e.
    #randomly trying other rates, to gather statistics. The percentage of
    #"look around" frames defaults to 10%. The distribution of lookaround frames is
    #also randomized somewhat to avoid any potential "strobing" of lookaround
    #between similar nodes.

    #Try |         Lookaround rate              | Normal rate
    #    | random < best    | random > best     |
    #--------------------------------------------------------------
    # 1  | Best throughput  | Random rate       | Best throughput
    # 2  | Random rate      | Best throughput   | Next best throughput
    # 3  | Best probability | Best probability  | Best probability
    # 4  | Lowest Baserate  | Lowest baserate   | Lowest baserate

    if rates[bestThruput].tban > 4:
        #print("Temp ban on {}, switching to {}!".format(bestThruput, nextThruput))
        rates[bestThruput].tban = 0
        bestThruput = nextThruput
        nextThruput = bestProb

    if randint(1, 100) <= 10 or rates[bestThruput].tban > 4:
        #Analysis of information showed that the system was sampling too hard
        #at some rates. For those rates that never work (54mb, 500m range)
        #there is no point in sending 10 sample packets (< 6 ms time). Consequently,
        #for the very very low probability rates, we sample at most twice.

        random = choice(list(rates))
        while (random == 1):  #never sample at lowest rate
            random = choice(list(rates))

        if random < bestThruput:
            r = [(ieee80211_to_idx(bestThruput),
                  rates[bestThruput].adjusted_retry_count),
                 (ieee80211_to_idx(random),
                  rates[random].adjusted_retry_count),
                 (ieee80211_to_idx(bestProb),
                  rates[bestProb].adjusted_retry_count),
                 (ieee80211_to_idx(lowestRate),
                  rates[lowestRate].adjusted_retry_count)]
        else:
            #TODO: understand the corresponding kernel code more
            #and implement if (if necessary)
            if rates[random].sample_limit != 0:
                if rates[random].sample_limit > 0:
                    rates[random].sample_limit -= 1

            r = [(ieee80211_to_idx(random),
                  rates[random].adjusted_retry_count),
                 (ieee80211_to_idx(bestThruput),
                  rates[bestThruput].adjusted_retry_count),
                 (ieee80211_to_idx(bestProb),
                  rates[bestProb].adjusted_retry_count),
                 (ieee80211_to_idx(lowestRate),
                  rates[lowestRate].adjusted_retry_count)]

    else:  #normal
        r = [(ieee80211_to_idx(bestThruput),
              rates[bestThruput].adjusted_retry_count),
             (ieee80211_to_idx(nextThruput),
              rates[nextThruput].adjusted_retry_count),
             (ieee80211_to_idx(bestProb),
              rates[bestProb].adjusted_retry_count),
             (ieee80211_to_idx(lowestRate),
              rates[lowestRate].adjusted_retry_count)]
    return r
Ejemplo n.º 9
0
def tx_time(rate, length):  #rate is Mbps, length in bytes
    return common.tx_time(ieee80211_to_idx(rate), length)
Ejemplo n.º 10
0
def apply_rate(cur_time):  #cur_time is in nanoseconds
    global npkts, nsuccess, nlookaround, NBYTES, currRate, NRETRIES, np, nd
    global bestThruput, nextThruput, bestProb, lowestRate, time_last_called

    if cur_time - time_last_called >= 1e8:
        update_stats(cur_time)
        time_last_called = cur_time

    #Minstrel spends a particular percentage of frames, doing "look around" i.e.
    #randomly trying other rates, to gather statistics. The percentage of
    #"look around" frames defaults to 10%. The distribution of lookaround frames is
    #also randomized somewhat to avoid any potential "strobing" of lookaround
    #between similar nodes.

    #Try |         Lookaround rate              | Normal rate
    #    | random < best    | random > best     |
    #--------------------------------------------------------------
    # 1  | Best throughput  | Random rate       | Best throughput
    # 2  | Random rate      | Best throughput   | Next best throughput
    # 3  | Best probability | Best probability  | Best probability
    # 4  | Lowest Baserate  | Lowest baserate   | Lowest baserate
    delta = (npkts * .1 - (np + nd / 2.0))
    if delta > 0:  #random!
        #Analysis of information showed that the system was sampling too hard
        #at some rates. For those rates that never work (54mb, 500m range)
        #there is no point in sending 10 sample packets (< 6 ms time). Consequently,
        #for the very very low probability rates, we sample at most twice.

        if npkts >= 10000:
            np = 0
            npkts = 0
            nd = 0
        elif delta > len(rates) * 2:
            '''FROM KERNEL COMMENTS:
            /* With multi-rate retry, not every planned sample          
            * attempt actually gets used, due to the way the retry     
            * chain is set up - [max_tp,sample,prob,lowest] for        
            * sample_rate < max_tp.                                    
            *                                                          
            * If there's too much sampling backlog and the link        
            * starts getting worse, minstrel would start bursting      
            * out lots of sampling frames, which would result          
            * in a large throughput loss. */'''
            np += delta - (len(rates) * 2)

        random = choice(list(rates))
        while (random == 1):  #never sample at lowest rate
            random = choice(list(rates))

        if random < bestThruput:
            chain = [bestThruput, random, bestProb, lowestRate]
            ''' FROM KERNEL:
            /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark        
            * packets that have the sampling rate deferred to the      
            * second MRR stage. Increase the sample counter only       
            * if the deferred sample rate was actually used.           
            * Use the sample_deferred counter to make sure that        
            * the sampling is not done in large bursts */'''
            probe_flag = True
            nd += 1

        else:
            #manages probe counting
            if rates[random].sample_limit != 0:
                np += 1
                if rates[random].sample_limit > 0:
                    rates[random].sample_limit -= 1

            chain = [random, bestThruput, bestProb, lowestRate]

    else:  #normal
        chain = [bestThruput, nextThruput, bestProb, lowestRate]

    mrr = [(ieee80211_to_idx(rate), rates[rate].adjusted_retry_count)
           for rate in chain]

    return mrr