Beispiel #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)]
def tx_time(mbps, length=1200): #rix is index to RATES, length in bytes
    '''
    Adapted from 802.11 util.c ieee80211_frame_duration()

    calculate duration (in microseconds, rounded up to next higher
    integer if it includes a fractional microsecond) to send frame of
    len bytes (does not include FCS) at the given rate. Duration will
    also include SIFS.
    '''

    rateinfo = rates.RATES[rates.ieee80211_to_idx(mbps)]

    if rateinfo.phy == "ofdm":
        '''
        OFDM:
        N_DBPS = DATARATE x 4
        N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
        (16 = SIGNAL time, 6 = tail bits)
        TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext

        T_SYM = 4 usec
        802.11a - 17.5.2: aSIFSTime = 16 usec
        802.11g - 19.8.4: aSIFSTime = 10 usec + signal ext = 6 usec
        '''
        dur = 16 # SIFS + signal ext */
        dur += 16 # 17.3.2.3: T_PREAMBLE = 16 usec */
        dur += 4 # 17.3.2.3: T_SIGNAL = 4 usec */
        dur += 4 * (math.ceil((16+8*(length+4)+6)/(4*mbps))+1) # T_SYM x N_SYM

    else:
        '''
        802.11b or 802.11g with 802.11b compatibility:
        18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
        Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.

        802.11 (DS): 15.3.3, 802.11b: 18.3.4
        aSIFSTime = 10 usec
        aPreambleLength = 144 usec or 72 usec with short preamble
        aPLCPHeaderLength = 48 usec or 24 usec with short preamble
        '''
        dur = 10 # aSIFSTime = 10 usec
        dur += (72 + 24) #using short preamble, otw we'd use (144 + 48)
        dur += math.ceil((8*(length + 4))/mbps)+1

    return dur
def apply_rate(cur_time):
    global packet_count, sample_count, sample_deferred, 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 = (packet_count * SAMPLING_RATIO // 100) - \
            (sample_count + sample_deferred // 2)

    if delta > 0: # In this case we attempt to sample a rate
        #"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 packet_count >= 10000:
            sample_count = 0
            packet_count = 0
            sample_deferred = 0
        elif delta > len(RATES) * 2:
            #"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."
            sample_count += delta  - (len(RATES)*2)

        # The kernel actually doesn't use a random number generator
        # here, instead using a pregenerated table of "random" numbers.
        # See net/mac80211/rc80211_minstrel.c :: init_sample_table

        # TODO: Use the mechanism the kernel uses
        randrate = random.choice(list(RATES.keys()))

	#"Decide if direct ( 1st mrr stage) or indirect (2nd mrr
	# stage) rate sampling method should be used.  Respect such
	# rates that are not sampled for 20 interations."

        if randrate < choices.best and RATES[randrate].sample_skipped < 20:
            #"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
            sample_deferred += 1

            chain = [choices.best, randrate, choices.prob, choices.base]
        else:
            if RATES[randrate].sample_limit != 0:
                sample_count += 1
                if RATES[randrate].sample_limit > 0:
                    RATES[randrate].sample_limit -= 1

            chain = [randrate, choices.best, choices.prob, choices.base]

    else:
        chain = [choices.best, choices.next, choices.prob, choices.base]

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

    return mrr
Beispiel #4
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
Beispiel #5
0
def bitrate_type(bitrate):
    return rates.RATES[ieee80211_to_idx(bitrate)].phy
def bitrate_type(bitrate):
    return rates.RATES[ieee80211_to_idx(bitrate)].phy