1 /**************************************************************************/
2 /* ---------------------------------------------------------------------- */
3 /* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
5 /* Universidad de Cantabria, SPAIN */
6 /* University of York, UK */
7 /* Scuola Superiore Sant'Anna, ITALY */
8 /* Kaiserslautern University, GERMANY */
9 /* Univ. Politécnica Valencia, SPAIN */
10 /* Czech Technical University in Prague, CZECH REPUBLIC */
12 /* Thales Communication S.A. FRANCE */
13 /* Visual Tools S.A. SPAIN */
14 /* Rapita Systems Ltd UK */
17 /* See http://www.frescor.org for a link to partners' websites */
19 /* FRESCOR project (FP6/2005/IST/5-034026) is funded */
20 /* in part by the European Union Sixth Framework Programme */
21 /* The European Union is not liable of any use that may be */
22 /* made of this code. */
25 /* This file is part of FWP (Frescor WLAN Protocol) */
27 /* FWP is free software; you can redistribute it and/or modify it */
28 /* under terms of the GNU General Public License as published by the */
29 /* Free Software Foundation; either version 2, or (at your option) any */
30 /* later version. FWP is distributed in the hope that it will be */
31 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
32 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
33 /* General Public License for more details. You should have received a */
34 /* copy of the GNU General Public License along with FWP; see file */
35 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
36 /* Cambridge, MA 02139, USA. */
38 /* As a special exception, including FWP header files in a file, */
39 /* instantiating FWP generics or templates, or linking other files */
40 /* with FWP objects to produce an executable application, does not */
41 /* by itself cause the resulting executable application to be covered */
42 /* by the GNU General Public License. This exception does not */
43 /* however invalidate any other reasons why the executable file might be */
44 /* covered by the GNU Public License. */
45 /**************************************************************************/
46 #include <fres_sa_scenario.h>
49 #include "fwp_admctrl.h"
51 /* TODO: Find out the real value and determine what influences it (MTU
52 * of the interface minus header sizes?). */
54 #define UDP_HEADER_SIZE 8
55 #define IP_HEADER_SIZE 20
56 #define LLC_HEADER_SIZE 2 /* ??? */
57 #define MAC_HEADER_SIZE 26 /* With QoS field added */
58 #define MAC_FCS_SIZE 4
60 #define RTS_FRAME_SIZE 20
61 #define CTS_FRAME_SIZE 14
62 #define ACK_FRAME_SIZE 14
64 #define BITRATE_BPS (1000*1000)
65 #define ASLOTTIME_USEC 20 /* 802.11g-2003 p. 46 */
66 #define ASIFSTIME_USEC 10
67 #define ADIFSTIME_USEC (ASIFSTIME_USEC + 2*ASLOTTIME_USEC)
68 #define AAIFSTIME_USEC(n) (ASIFSTIME_USEC + (n)*ASLOTTIME_USEC)
70 #define TXTIME_USEC(bytes) ((int64_t)(bytes) * 8 * SEC_TO_USEC / BITRATE_BPS)
73 /* Default values from 802.11e */
74 const int aifsn[FWP_AC_NUM] = { 2, 2, 3, 7 };
75 const int cwmin[FWP_AC_NUM] = { 3, 7, 15, 15 };
77 /* Experimental konstants - weight of backoff */
78 const int pisvejc[FWP_AC_NUM] = { 6, 5, 2, 2 };
80 int fwp_reserved_utilization;
83 * Calucaltes frame duration in microseconds. If the real duration is
84 * represented by a fractional number, the value is rounded up.
86 * @param length Number of bytes in PSDU.
87 * @param rate_bps Transmit rate of PSDU. The rate should correspond
88 * to other parameters accoring to 19.3.2 (802.11g)
89 * @param erp_ofdm Whether Extended Rate PHY (part of 802.11g) and ERP-OFDM
91 * @param short_preamble Whether short preamble (HR/DSSS/short) is
94 * @return The number of microseconds or a negative number in case of error.
96 static int frame_duration(uint16_t length, int rate_bps, bool erp_ofdm, bool short_preamble)
98 uint32_t duration_usec = 0;
101 duration_usec = ((int64_t)(length) * 8 * SEC_TO_USEC / rate_bps);
102 if (short_preamble) {
103 /* For HR/DSSS/short (2, 5.5 and 11 Mbit,
104 * 802.11b-1999), also for DSSS-OFDM rates and
106 * Preamble sent at 1 MBit, header at 2 Mbit */
107 duration_usec += 72/*bits*/+48/*bits*//2;
109 /* For DSSS PHY (1 and 2 Mbit rates,
110 * 802.11-1999) and for DSS-OFDM and ERP-PBCC
111 * rates. Always sent at 1 MBit */
112 duration_usec += 144/*bits*/+48/*bits*/;
115 #define MBIT_TO_INDEX(rate_Mbps) ((rate_Mbps)/3 - 2)
116 const int N_dbps[] = {
117 [MBIT_TO_INDEX(6)] = 24,
118 [MBIT_TO_INDEX(9)] = 36,
119 [MBIT_TO_INDEX(12)] = 48,
120 [MBIT_TO_INDEX(18)] = 72,
121 [MBIT_TO_INDEX(24)] = 96,
122 [MBIT_TO_INDEX(36)] = 144,
123 [MBIT_TO_INDEX(48)] = 192,
124 [MBIT_TO_INDEX(54)] = 216
126 int rate_idx = MBIT_TO_INDEX(rate_bps/1000/1000);
129 rate_idx >= sizeof(N_dbps)/sizeof(*N_dbps) ||
130 N_dbps[rate_idx] == 0)
133 duration_usec += 16 + 4; /* Preamble, SIGNAL */
138 int Nsym = (bits + N_dbps[rate_idx] - 1)/N_dbps[rate_idx];
140 duration_usec += Nsym * 4;
142 duration_usec += 6; /* signal extension */
144 return duration_usec;
147 int fwp_admctrl_utilization(struct fres_sa_scenario *scenario, void *priv,
152 const int rate = 1*1000*1000;
153 const bool erp_ofdm = false;
154 const bool short_preamble = false;
155 struct fres_sa_contract *c, *c_new = NULL;
156 long int period_usec;
157 fres_block_basic *basic;
158 fres_block_fwp_sched *fwp_sched;
161 long int duration_usec, tmp_usec;
165 fres_sa_scenario_for_each_contract(scenario, c) {
166 fres_block_basic *basic;
168 fres_contract_id_to_string(id, &c->contract->id, sizeof(id));
169 basic = fres_contract_get_basic(c->contract);
171 frsh_network_budget_to_bytes(FRSH_NETPF_FWP,&basic->budget,&bytes);
172 printf(" processing: id=%s, period=%ld ms, budget=%lu bytes\n",
174 fosa_rel_time_to_msec(basic->period),
175 (long unsigned int)bytes);
177 /* Calculate protocol overhead */
178 fragments = (bytes + MTU - 1) / MTU;
183 const int data_overhead = UDP_HEADER_SIZE + IP_HEADER_SIZE +
184 LLC_HEADER_SIZE + MAC_FCS_SIZE;
186 duration_usec = frame_duration(data_overhead + bytes%MTU, rate,
187 erp_ofdm, short_preamble);
188 tmp_usec = frame_duration(data_overhead + MTU, rate, erp_ofdm,
190 duration_usec += tmp_usec*(fragments-1);
191 /* Add average backoff - assume there is no collision */
192 tmp_usec = ASLOTTIME_USEC*fragments*pisvejc[ac];
193 duration_usec += (aifsn[ac] + cwmin[ac]/2)*tmp_usec;
194 /* We use ACK and ignore burst */
195 tmp_usec = frame_duration(ACK_FRAME_SIZE, rate, erp_ofdm,
196 short_preamble) + ASIFSTIME_USEC;
197 duration_usec += fragments * tmp_usec;
199 /* TODO: If STA-to-STA, multiply it by two. Note that
200 * AP may use different values for backoff. */
201 duration_usec *= 2; /* For demo, we have always STA-to-STA */
203 basic = fres_contract_get_basic(c->contract);
204 period_usec = fosa_rel_time_to_msec(basic->period)*1000;
205 if (c->contract == c->new) {
207 if (period_usec == 0) {
208 goto not_schedulable;
211 utilization += (long long)(duration_usec * 10000) / period_usec;
215 *schedulable = false;
218 if (utilization >= 10000 * 96/100) {
219 goto not_schedulable;
222 basic = fres_contract_get_basic(c_new->contract);
223 /*int d = c->deadline_usec;*/
224 long int d = fosa_rel_time_to_msec(basic->period)*1000;
225 if (d <= 0) d = 100*1000*1000;
227 goto not_schedulable;
231 fwp_sched = malloc(sizeof(*fwp_sched));
233 d < 100*1000 ? FWP_AC_VO :
234 d < 500*1000 ? FWP_AC_VI :
235 d < 1000*1000 ? FWP_AC_BE :
237 fres_contract_add_block(c_new->contract, FRES_BLOCK_FWP_SCHED, fwp_sched);
241 *schedulable = false;