LCOV - code coverage report
Current view: top level - net80211 - ieee80211_rssadapt.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 63 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ieee80211_rssadapt.c,v 1.11 2014/12/23 03:24:08 tedu Exp $    */
       2             : /*      $NetBSD: ieee80211_rssadapt.c,v 1.7 2004/05/25 04:33:59 dyoung Exp $    */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or
       8             :  * without modification, are permitted provided that the following
       9             :  * conditions are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above
      13             :  *    copyright notice, this list of conditions and the following
      14             :  *    disclaimer in the documentation and/or other materials provided
      15             :  *    with the distribution.
      16             :  *
      17             :  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
      18             :  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
      19             :  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
      20             :  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
      21             :  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      22             :  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
      23             :  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      24             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      25             :  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
      26             :  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      27             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
      28             :  * OF SUCH DAMAGE.
      29             :  */
      30             : 
      31             : #include <sys/param.h>
      32             : #include <sys/systm.h>
      33             : #include <sys/kernel.h>
      34             : #include <sys/socket.h>
      35             : 
      36             : #include <net/if.h>
      37             : #include <net/if_media.h>
      38             : 
      39             : #include <netinet/in.h>
      40             : #include <netinet/if_ether.h>
      41             : 
      42             : #include <net80211/ieee80211_var.h>
      43             : #include <net80211/ieee80211_rssadapt.h>
      44             : 
      45             : #ifdef interpolate
      46             : #undef interpolate
      47             : #endif
      48             : #define interpolate(parm, old, new)                             \
      49             :         ((parm##_old * (old) +                                  \
      50             :         (parm##_denom - parm##_old) * (new)) / parm##_denom)
      51             : 
      52             : #ifdef IEEE80211_DEBUG
      53             : static  struct timeval lastrateadapt;   /* time of last rate adaptation msg */
      54             : static  int currssadaptps = 0;          /* rate-adaptation msgs this second */
      55             : static  int ieee80211_adaptrate = 4;    /* rate-adaptation max msgs/sec */
      56             : 
      57             : #define RSSADAPT_DO_PRINT() \
      58             :         ((ieee80211_rssadapt_debug > 0) && \
      59             :          ppsratecheck(&lastrateadapt, &currssadaptps, ieee80211_adaptrate))
      60             : #define RSSADAPT_PRINTF(X) \
      61             :         if (RSSADAPT_DO_PRINT()) \
      62             :                 printf X
      63             : 
      64             : int ieee80211_rssadapt_debug = 0;
      65             : 
      66             : #else
      67             : #define RSSADAPT_DO_PRINT() (0)
      68             : #define RSSADAPT_PRINTF(X)
      69             : #endif
      70             : 
      71             : static const struct ieee80211_rssadapt_expavgctl master_expavgctl = {
      72             :         .rc_decay_denom         = 16,
      73             :         .rc_decay_old           = 15,
      74             :         .rc_thresh_denom        = 8,
      75             :         .rc_thresh_old          = 4,
      76             :         .rc_avgrssi_denom       = 8,
      77             :         .rc_avgrssi_old         = 4
      78             : };
      79             : 
      80             : int
      81           0 : ieee80211_rssadapt_choose(struct ieee80211_rssadapt *ra,
      82             :     const struct ieee80211_rateset *rs, const struct ieee80211_frame *wh,
      83             :     u_int len, int fixed_rate, const char *dvname, int do_not_adapt)
      84             : {
      85             :         u_int16_t (*thrs)[IEEE80211_RATE_SIZE];
      86             :         int flags = 0, i, rateidx = 0, thridx, top;
      87             : 
      88           0 :         if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
      89           0 :                 flags |= IEEE80211_RATE_BASIC;
      90             : 
      91           0 :         for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
      92           0 :              i < IEEE80211_RSSADAPT_BKTS;
      93           0 :              i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
      94             :                 thridx = i;
      95           0 :                 if (len <= top)
      96             :                         break;
      97             :         }
      98             : 
      99           0 :         thrs = &ra->ra_rate_thresh[thridx];
     100             : 
     101           0 :         if (fixed_rate != -1) {
     102           0 :                 if ((rs->rs_rates[fixed_rate] & flags) == flags) {
     103             :                         rateidx = fixed_rate;
     104           0 :                         goto out;
     105             :                 }
     106             :                 flags |= IEEE80211_RATE_BASIC;
     107             :                 i = fixed_rate;
     108           0 :         } else
     109           0 :                 i = rs->rs_nrates;
     110             : 
     111           0 :         while (--i >= 0) {
     112             :                 rateidx = i;
     113           0 :                 if ((rs->rs_rates[i] & flags) != flags)
     114           0 :                         continue;
     115           0 :                 if (do_not_adapt)
     116             :                         break;
     117           0 :                 if ((*thrs)[i] < ra->ra_avg_rssi)
     118             :                         break;
     119             :         }
     120             : 
     121             : out:
     122             : #ifdef IEEE80211_DEBUG
     123             :         if (ieee80211_rssadapt_debug && dvname != NULL) {
     124             :                 printf("%s: dst %s threshold[%d, %d.%d] %d < %d\n",
     125             :                     dvname, ether_sprintf((u_int8_t *)wh->i_addr1), len,
     126             :                     (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) / 2,
     127             :                     (rs->rs_rates[rateidx] & IEEE80211_RATE_VAL) * 5 % 10,
     128             :                     (*thrs)[rateidx], ra->ra_avg_rssi);
     129             :         }
     130             : #endif /* IEEE80211_DEBUG */
     131           0 :         return rateidx;
     132             : }
     133             : 
     134             : void
     135           0 : ieee80211_rssadapt_updatestats(struct ieee80211_rssadapt *ra)
     136             : {
     137             :         long interval;
     138             : 
     139           0 :         ra->ra_pktrate =
     140           0 :             (ra->ra_pktrate + 10 * (ra->ra_nfail + ra->ra_nok)) / 2;
     141           0 :         ra->ra_nfail = ra->ra_nok = 0;
     142             : 
     143             :         /* a node is eligible for its rate to be raised every 1/10 to 10
     144             :          * seconds, more eligible in proportion to recent packet rates.
     145             :          */
     146           0 :         interval = MAX(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate));
     147           0 :         ra->ra_raise_interval.tv_sec = interval / (1000 * 1000);
     148           0 :         ra->ra_raise_interval.tv_usec = interval % (1000 * 1000);
     149           0 : }
     150             : 
     151             : void
     152           0 : ieee80211_rssadapt_input(struct ieee80211com *ic,
     153             :     const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra, int rssi)
     154             : {
     155             : #ifdef IEEE80211_DEBUG
     156             :         int last_avg_rssi = ra->ra_avg_rssi;
     157             : #endif
     158             : 
     159           0 :         ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi,
     160             :             ra->ra_avg_rssi, (rssi << 8));
     161             : 
     162             :         RSSADAPT_PRINTF(("%s: src %s rssi %d avg %d -> %d\n",
     163             :             ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr),
     164             :             rssi, last_avg_rssi, ra->ra_avg_rssi));
     165           0 : }
     166             : 
     167             : /*
     168             :  * Adapt the data rate to suit the conditions.  When a transmitted
     169             :  * packet is dropped after IEEE80211_RSSADAPT_RETRY_LIMIT retransmissions,
     170             :  * raise the RSS threshold for transmitting packets of similar length at
     171             :  * the same data rate.
     172             :  */
     173             : void
     174           0 : ieee80211_rssadapt_lower_rate(struct ieee80211com *ic,
     175             :     const struct ieee80211_node *ni, struct ieee80211_rssadapt *ra,
     176             :     const struct ieee80211_rssdesc *id)
     177             : {
     178           0 :         const struct ieee80211_rateset *rs = &ni->ni_rates;
     179             :         u_int16_t last_thr;
     180             :         u_int i, thridx, top;
     181             : 
     182           0 :         ra->ra_nfail++;
     183             : 
     184           0 :         if (id->id_rateidx >= rs->rs_nrates) {
     185             :                 RSSADAPT_PRINTF(("ieee80211_rssadapt_lower_rate: "
     186             :                     "%s rate #%d > #%d out of bounds\n",
     187             :                     ether_sprintf((u_int8_t *)ni->ni_macaddr), id->id_rateidx,
     188             :                     rs->rs_nrates - 1));
     189           0 :                 return;
     190             :         }
     191             : 
     192           0 :         for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
     193           0 :              i < IEEE80211_RSSADAPT_BKTS;
     194           0 :              i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
     195             :                 thridx = i;
     196           0 :                 if (id->id_len <= top)
     197             :                         break;
     198             :         }
     199             : 
     200           0 :         last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx];
     201           0 :         ra->ra_rate_thresh[thridx][id->id_rateidx] =
     202           0 :             interpolate(master_expavgctl.rc_thresh, last_thr,
     203             :             (id->id_rssi << 8));
     204             : 
     205             :         RSSADAPT_PRINTF(("%s: dst %s rssi %d threshold[%d, %d.%d] %d -> %d\n",
     206             :             ic->ic_if.if_xname, ether_sprintf((u_int8_t *)ni->ni_macaddr),
     207             :             id->id_rssi, id->id_len,
     208             :             (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) / 2,
     209             :             (rs->rs_rates[id->id_rateidx] & IEEE80211_RATE_VAL) * 5 % 10,
     210             :             last_thr, ra->ra_rate_thresh[thridx][id->id_rateidx]));
     211           0 : }
     212             : 
     213             : void
     214           0 : ieee80211_rssadapt_raise_rate(struct ieee80211com *ic,
     215             :     struct ieee80211_rssadapt *ra, const struct ieee80211_rssdesc *id)
     216             : {
     217             :         u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr;
     218           0 :         const struct ieee80211_node *ni = id->id_node;
     219           0 :         const struct ieee80211_rateset *rs = &ni->ni_rates;
     220             :         int i, rate, top;
     221             : #ifdef IEEE80211_DEBUG
     222             :         int j;
     223             : #endif
     224             : 
     225           0 :         ra->ra_nok++;
     226             : 
     227           0 :         if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval))
     228           0 :                 return;
     229             : 
     230           0 :         for (i = 0, top = IEEE80211_RSSADAPT_BKT0;
     231           0 :              i < IEEE80211_RSSADAPT_BKTS;
     232           0 :              i++, top <<= IEEE80211_RSSADAPT_BKTPOWER) {
     233           0 :                 thrs = &ra->ra_rate_thresh[i];
     234           0 :                 if (id->id_len <= top)
     235             :                         break;
     236             :         }
     237             : 
     238           0 :         if (id->id_rateidx + 1 < rs->rs_nrates &&
     239           0 :             (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) {
     240           0 :                 rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL);
     241             : 
     242             :                 RSSADAPT_PRINTF(("%s: threshold[%d, %d.%d] decay %d ",
     243             :                     ic->ic_if.if_xname, IEEE80211_RSSADAPT_BKT0 <<
     244             :                         (IEEE80211_RSSADAPT_BKTPOWER * i),
     245             :                     rate / 2, rate * 5 % 10, (*thrs)[id->id_rateidx + 1]));
     246             :                 oldthr = (*thrs)[id->id_rateidx + 1];
     247           0 :                 if ((*thrs)[id->id_rateidx] == 0)
     248           0 :                         newthr = ra->ra_avg_rssi;
     249             :                 else
     250             :                         newthr = (*thrs)[id->id_rateidx];
     251           0 :                 (*thrs)[id->id_rateidx + 1] =
     252           0 :                     interpolate(master_expavgctl.rc_decay, oldthr, newthr);
     253             : 
     254             :                 RSSADAPT_PRINTF(("-> %d\n", (*thrs)[id->id_rateidx + 1]));
     255           0 :         }
     256             : 
     257             : #ifdef IEEE80211_DEBUG
     258             :         if (RSSADAPT_DO_PRINT()) {
     259             :                 printf("%s: dst %s thresholds\n", ic->ic_if.if_xname,
     260             :                     ether_sprintf((u_int8_t *)ni->ni_macaddr));
     261             :                 for (i = 0; i < IEEE80211_RSSADAPT_BKTS; i++) {
     262             :                         printf("%d-byte", IEEE80211_RSSADAPT_BKT0 <<
     263             :                             (IEEE80211_RSSADAPT_BKTPOWER * i));
     264             :                         for (j = 0; j < rs->rs_nrates; j++) {
     265             :                                 rate = (rs->rs_rates[j] & IEEE80211_RATE_VAL);
     266             :                                 printf(", T[%d.%d] = %d", rate / 2,
     267             :                                     rate * 5 % 10, ra->ra_rate_thresh[i][j]);
     268             :                         }
     269             :                         printf("\n");
     270             :                 }
     271             :         }
     272             : #endif /* IEEE80211_DEBUG */
     273           0 : }

Generated by: LCOV version 1.13