1 #include <fres_sa_scenario.h>
3 /* TODO: Find out the real value and determine what influences it (MTU
4 * of the interface minus header sizes?). */
6 #define UDP_HEADER_SIZE 8
7 #define IP_HEADER_SIZE 20
8 #define LLC_HEADER_SIZE 2 /* ??? */
9 #define MAC_HEADER_SIZE 26 /* With QoS field added */
10 #define MAC_FCS_SIZE 4
12 #define RTS_FRAME_SIZE 20
13 #define CTS_FRAME_SIZE 14
14 #define ACK_FRAME_SIZE 14
16 #define BITRATE_BPS (1000*1000)
17 #define ASLOTTIME_USEC 20 /* 802.11g-2003 p. 46 */
18 #define ASIFSTIME_USEC 10
19 #define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
20 #define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
22 #define TXTIME_USEC(bytes) ((int64_t)(bytes) * 8 * SEC_TO_USEC / BITRATE_BPS)
25 /* Default values from 802.11e */
26 const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
27 const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
29 /* Experimental konstants - weight of backoff */
30 const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
32 int fwp_reserved_utilization;
35 * Calucaltes frame duration in microseconds. If the real duration is
36 * represented by a fractional number, the value is rounded up.
38 * @param length Number of bytes in PSDU.
39 * @param rate_bps Transmit rate of PSDU. The rate should correspond
40 * to other parameters accoring to 19.3.2 (802.11g)
41 * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
43 * @param short_preamble Whether short preamble (HR/DSSS/short) is
46 * @return The number of microseconds or a negative number in case of error.
48 static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
50 uint32_t duration_usec;
53 duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
55 /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
56 * 802.11b-1999), also for DSSS-OFDM rates and
58 * Preamble sent at 1 MBit, header at 2 Mbit */
59 duration_usec += 72/*bits*/+48/*bits*//2;
61 /* For DSSS PHY (1 and 2 Mbit rates,
62 * 802.11-1999) and for DSS-OFDM and ERP-PBCC
63 * rates. Always sent at 1 MBit */
64 duration_usec += 144/*bits*/+48/*bits*/;
67 #define MBIT_TO_INDEX(rate_Mbps) ((rate_Mbps)/3 - 2)
68 const int N_dbps[] = {
69 [MBIT_TO_INDEX(6)] = 24,
70 [MBIT_TO_INDEX(9)] = 36,
71 [MBIT_TO_INDEX(12)] = 48,
72 [MBIT_TO_INDEX(18)] = 72,
73 [MBIT_TO_INDEX(24)] = 96,
74 [MBIT_TO_INDEX(36)] = 144,
75 [MBIT_TO_INDEX(48)] = 192,
76 [MBIT_TO_INDEX(54)] = 216
78 int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
81 rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
82 N_dbps[rate_idx] == 0)
85 duration_usec += 16 + 4; /* Preamble, SIGNAL */
90 int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
92 duration_usec += Nsym * 4;
94 duration_usec += 6; /* signal extension */
99 int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
104 const int rate = 1*1000*1000;
105 const bool erp_ofdm = false;
106 const bool short_preamble = false;
108 int bytes, duration_usec, tmp_usec, fragments;
109 int ac = FWP_AC_VO; /* FIXME: assign to AC before this
110 * loop based on deadlines */
112 fres_sa_scenario_for_each_contract(scenario, c) {
113 fres_block_basic *basic;
115 fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
116 basic = fres_contract_get_basic(c->contract);
118 printf(" processing: id=%s, period=%ld ms, budget=%ld ms\n",
120 fosa_rel_time_to_msec(basic->period),
121 fosa_rel_time_to_msec(basic->budget));
123 /* Calculate protocol overhead */
124 bytes = fwp_fna_network_budget_to_bytes(basic->budget);
125 fragments = (bytes + MTU - 1) / MTU;
130 const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
131 LLC_HEADER_SIZE + MAC_FCS_SIZE;
133 duration_usec = frame_duration(data_overhead + bytes%MTU, rate,
134 erp_ofdm, short_preamble);
135 tmp_usec = frame_duration(data_overhead + MTU, rate, erp_ofdm,
137 duration_usec += tmp_usec*(fragments-1);
138 /* Add average backoff - assume there is no collision */
139 tmp_usec = ASLOTTIME_USEC*fragments*pisvejc[ac];
140 duration_usec += (aifsn[ac] + cwmin[ac]/2)*tmp_usec;
141 /* We use ACK and ignore burst */
142 tmp_usec = frame_duration(ACK_FRAME_SIZE, rate, erp_ofdm,
143 short_preamble) + ASIFSTIME_USEC;
144 duration_usec += fragments * tmp_usec;
146 /* TODO: If STA-to-STA, multiply it by two. Note that
147 * AP may use different values for backoff. */
148 duration_usec *= 2; /* For demo, we have always STA-to-STA */
149 if (contract->period_usec == 0) {
150 if (contdata == contdata_new) {
151 contdata->status = FWP_CONT_NOTNEGOTIATED;
155 utilization += (long long)(duration_usec * 10000) / contract->period_usec;
159 if (utilization >= 10000 * 96/100) {
160 contdata_new->status = FWP_CONT_NOTNEGOTIATED;
162 struct fwp_contract *c = &contdata_new->contract;
163 int d = c->deadline_usec;
164 if (d <= 0) d = 100*1000*1000;
166 contdata_new->status = FWP_CONT_NOTNEGOTIATED;
168 contdata_new->status = FWP_CONT_RESERVED;
171 contdata_new->vres_params.ac_id =
172 d < 100*1000 ? FWP_AC_VO :
173 d < 500*1000 ? FWP_AC_VI :
174 d < 1000*1000 ? FWP_AC_BE :
176 contdata_new->vres_params.budget = c->budget;
177 contdata_new->vres_params.period_usec = c->period_usec;
181 /* Update utilization for GUI */
182 if (contdata_new == NULL || contdata_new->status == FWP_CONT_RESERVED) {
183 fwp_reserved_utilization = utilization;