]> rtime.felk.cvut.cz Git - frescor/frsh-forb.git/blob - src/fwp/fwp/old.mngr/admtest_utilization.c
babee4b2c1ac76e21260f795f7ae4846d072db14
[frescor/frsh-forb.git] / src / fwp / fwp / old.mngr / admtest_utilization.c
1 #include "fwp_admctrl.h"
2 #include <fwp_utils.h>
3 #include <stdint.h>
4 #include <fwp_conf.h>
5 #include <stdbool.h>
6 #include <fwp_participant.h>
7 #include "fwp_participant_table.h"
8 #include "fwp_foreach.h"
9
10 /* TODO: Find out the real value and determine what influences it (MTU
11  *       of the interface minus header sizes?).  */
12 #define MTU 1472
13 #define UDP_HEADER_SIZE 8
14 #define IP_HEADER_SIZE 20
15 #define LLC_HEADER_SIZE 2       /* ??? */
16 #define MAC_HEADER_SIZE 26      /* With QoS field added */
17 #define MAC_FCS_SIZE 4
18
19 #define RTS_FRAME_SIZE 20
20 #define CTS_FRAME_SIZE 14
21 #define ACK_FRAME_SIZE 14
22
23 #define BITRATE_BPS (1000*1000)
24 #define ASLOTTIME_USEC 20       /* 802.11g-2003 p. 46 */
25 #define ASIFSTIME_USEC 10
26 #define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
27 #define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
28
29 #define TXTIME_USEC(bytes) ((int64_t)(bytes) * 8 * SEC_TO_USEC / BITRATE_BPS)
30
31
32 /* Default values from 802.11e */
33 const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
34 const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
35
36 /* Experimental konstants - weight of backoff */
37 const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
38
39 int fwp_reserved_utilization;
40
41 /**
42  * Calucaltes frame duration in microseconds. If the real duration is
43  * represented by a fractional number, the value is rounded up.
44  *
45  * @param length Number of bytes in PSDU.
46  * @param rate_bps Transmit rate of PSDU. The rate should correspond
47  *            to other parameters accoring to 19.3.2 (802.11g)
48  * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
49  *            modulation is used.
50  * @param short_preamble Whether short preamble (HR/DSSS/short) is
51  *            used (802.11b)
52  *
53  * @return The number of microseconds or a negative number in case of error.
54  */
55 static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
56 {
57         uint32_t duration_usec;
58
59         if (!erp_ofdm) {
60                 duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
61                 if (short_preamble) {
62                         /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
63                          * 802.11b-1999), also for DSSS-OFDM rates and
64                          * ERP-PBCC rates.
65                          * Preamble sent at 1 MBit, header at 2 Mbit */
66                         duration_usec += 72/*bits*/+48/*bits*//2;
67                 } else {
68                         /* For DSSS PHY (1 and 2 Mbit rates,
69                          * 802.11-1999) and for DSS-OFDM and ERP-PBCC
70                          * rates. Always sent at 1 MBit */
71                         duration_usec += 144/*bits*/+48/*bits*/;
72                 }
73         } else {
74 #define MBIT_TO_INDEX(rate_Mbps)  ((rate_Mbps)/3 - 2)
75                 const int N_dbps[] = {
76                         [MBIT_TO_INDEX(6)] = 24,
77                         [MBIT_TO_INDEX(9)] = 36,
78                         [MBIT_TO_INDEX(12)] = 48,
79                         [MBIT_TO_INDEX(18)] = 72,
80                         [MBIT_TO_INDEX(24)] = 96,
81                         [MBIT_TO_INDEX(36)] = 144,
82                         [MBIT_TO_INDEX(48)] = 192,
83                         [MBIT_TO_INDEX(54)] = 216
84                 };
85                 int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
86 #undef MBIT_TO_INDEX
87                 if (rate_idx < 0 ||
88                     rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
89                     N_dbps[rate_idx] == 0)
90                         return -1;
91
92                 duration_usec += 16 + 4; /* Preamble, SIGNAL */
93                 int bits =
94                         16 +        /* SERVICE */
95                         length * 8 +
96                         6;          /* tail bits */
97                 int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
98
99                 duration_usec += Nsym * 4;
100
101                 duration_usec += 6; /* signal extension */
102         }
103         return duration_usec;
104 }
105
106 void fwp_admctrl_utilization(fwp_contract_data_t *contdata_new)
107 {
108         int utilization = 0;
109
110         const int rate = 1*1000*1000;
111         const bool erp_ofdm = false;
112         const bool short_preamble = false;
113         fwp_contract_data_t *contdata;
114
115         struct foreach_contract fec;
116         fec.contdata_new = contdata_new;
117         
118         for (contdata=foreach_contract_begin(&fec);
119              contdata;
120              contdata=foreach_contract_next(&fec)) {
121                 int bytes, duration_usec, fragments;
122                 struct fwp_contract *contract = &contdata->contract;
123                 int ac = FWP_AC_VO; /* FIXME: assign to AC before this
124                                      * loop based on deadlines */
125                 /* Calculate protocol overhead */
126
127                 bytes = contract->budget;
128                 fragments = (bytes + MTU - 1) / MTU;
129
130                 if (fragments == 0)
131                         continue;
132
133                 const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
134                         LLC_HEADER_SIZE + MAC_FCS_SIZE;
135
136                 duration_usec = frame_duration(data_overhead + bytes%MTU, rate, erp_ofdm, short_preamble);
137                 duration_usec += frame_duration(data_overhead + MTU, rate, erp_ofdm, short_preamble)*(fragments-1);
138
139                 /* Add average backoff - assume there is no collision */
140                 duration_usec += (aifsn[ac] + cwmin[ac]/2)*ASLOTTIME_USEC*fragments*pisvejc[ac];
141                 /* We use ACK and ignore burst */
142                 duration_usec += fragments * (ASIFSTIME_USEC +
143                                   frame_duration(ACK_FRAME_SIZE, rate, erp_ofdm, short_preamble));
144
145                 /* TODO: If STA-to-STA, multiply it by two. Note that
146                  * AP may use different values for backoff. */
147                 duration_usec *= 2; /* For demo, we have always STA-to-STA */
148                 if (contract->period_usec == 0) {
149                         if (contdata == contdata_new) {
150                                 contdata->status = FWP_CONT_NOTNEGOTIATED;
151                                 return;
152                         }
153                 }
154                 utilization += (long long)(duration_usec * 10000) / contract->period_usec;
155         }
156
157         if (contdata_new) {
158                 if (utilization >= 10000 * 96/100) {
159                         contdata_new->status = FWP_CONT_NOTNEGOTIATED;
160                 } else {
161                         struct fwp_contract *c = &contdata_new->contract;
162                         int d = c->deadline_usec;
163                         if (d <= 0) d = 100*1000*1000;
164                         if (d < 50000) {
165                                 contdata_new->status = FWP_CONT_NOTNEGOTIATED;
166                         } else {
167                                 contdata_new->status = FWP_CONT_RESERVED;
168                         }
169
170                         contdata_new->vres_params.ac_id =
171                                 d <  100*1000 ? FWP_AC_VO :
172                                 d <  500*1000 ? FWP_AC_VI :
173                                 d < 1000*1000 ? FWP_AC_BE :
174                                 FWP_AC_BK;
175                         contdata_new->vres_params.budget = c->budget;
176                         contdata_new->vres_params.period_usec = c->period_usec; 
177                 }
178         }
179
180         /* Update utilization for GUI */
181         if (contdata_new == NULL || contdata_new->status == FWP_CONT_RESERVED) {
182                 fwp_reserved_utilization = utilization;
183         }
184 }