]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres.c
licenses
[frescor/fna.git] / src_frescan / frescan_bwres.c
1 /*!
2  * @file frescan_bwres.c
3  *
4  * @brief FRESCAN bandwidth reservation layer
5  *
6  * This module contains function to negotiate contracts and get the
7  * corresponding frescan sporadic servers.
8  *
9  * @version 0.01
10  *
11  * @date 1-Apr-2008
12  *
13  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
14  *
15  * @license
16  *
17  * -----------------------------------------------------------------------
18  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
19  *
20  *    Universidad de Cantabria,              SPAIN
21  *    University of York,                    UK
22  *    Scuola Superiore Sant'Anna,            ITALY
23  *    Kaiserslautern University,             GERMANY
24  *    Univ. Politécnica  Valencia,           SPAIN
25  *    Czech Technical University in Prague,  CZECH REPUBLIC
26  *    ENEA                                   SWEDEN
27  *    Thales Communication S.A.              FRANCE
28  *    Visual Tools S.A.                      SPAIN
29  *    Rapita Systems Ltd                     UK
30  *    Evidence                               ITALY
31  *
32  *    See http://www.frescor.org for a link to partners' websites
33  *
34  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
35  *        in part by the European Union Sixth Framework Programme
36  *        The European Union is not liable of any use that may be
37  *        made of this code.
38  *
39  *  This file is part of FRESCAN
40  *
41  *  FRESCAN is free software; you can  redistribute it and/or  modify
42  *  it under the terms of  the GNU General Public License as published by
43  *  the Free Software Foundation;  either  version 2, or (at  your option)
44  *  any later version.
45  *
46  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
47  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
48  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
49  *  General Public License for more details.
50  *
51  *  You should have  received a  copy of  the  GNU  General Public License
52  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
53  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
54  *  02111-1307, USA.
55  *
56  * As a special exception, including FRESCAN header files in a file,
57  * instantiating FRESCAN generics or templates, or linking other files
58  * with FRESCAN objects to produce an executable application, does not
59  * by itself cause the resulting executable application to be covered
60  * by the GNU General Public License. This exception does not
61  * however invalidate any other reasons why the executable file might be
62  * covered by the GNU Public License.
63  * -----------------------------------------------------------------------
64  *
65  */
66
67 #include "frescan_bwres.h"
68 #include "frescan_bwres_requests.h"
69 #include "frescan_bwres_messages.h"
70 #include "frescan_bwres_threads.h"
71 #include "frescan_bwres_analysis.h"
72 #include "frescan_data.h"
73 #include "frescan_debug.h"
74 #include "frescan_config.h"
75 #include "frescan_servers.h"
76
77 /**
78  * frescan_bwres_init()
79  *
80  * Init the frescan bandwidth reservation layer
81  */
82
83 int frescan_bwres_init(frescan_network_t net)
84 {
85         int ret;
86         frescan_server_params_t  server_params;  // TODO: improve this...
87         frescan_sa_init_params_t sa_init_params; // TODO: improve this...
88
89         sa_init_params.max_prio = 30;
90         sa_init_params.min_prio = 1;
91
92         ret = frescan_sa_init(&the_networks[net].scenario,
93                               &sa_init_params);
94         if (ret != 0) return ret;
95
96         server_params.values.budget = 5;
97         server_params.values.period.tv_sec = 1;
98         server_params.values.period.tv_nsec = 0;
99         server_params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
100
101         ret = frescan_servers_create(net, &server_params,
102                                      &the_networks[net].neg_messages_ss_id);
103         if (ret != 0) return ret;
104
105         // TODO: we have to add this negotiation contracts to the sa table
106
107         ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
108         if (ret != 0) return ret;
109
110         ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
111         if (ret != 0) return ret;
112
113         ret = frescan_messages_init(net);
114         if (ret != 0) return ret;
115
116         ret = frescan_manager_thread_create(net);
117         if (ret != 0) return ret;
118
119         ret = frescan_acceptor_thread_create(net);
120         if (ret != 0) return ret;
121
122         return 0;
123 }
124
125 /**
126  * frescan_bwres_negotiate()
127  *
128  * to negotiate a contract we follow the next steps:
129  *
130  * 1.- prepare a request
131  * 2.- enqueue the request
132  * 3.- wait in the reply object for a reply
133  * 4.- return the final values and free the request
134  */
135
136 int frescan_bwres_negotiate(frescan_network_t net,
137                             const frescan_contract_t *contract,
138                             frescan_ss_t *ss,
139                             bool *accepted)
140 {
141         int ret;
142         frescan_request_id_t   req;
143         frescan_request_data_t *req_data;
144         frescan_server_params_t server_params;
145
146         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
147
148         ret = frescan_requests_alloc(&req);
149         if (ret != 0) return ret;
150
151         ret = frescan_requests_get_data(req, &req_data);
152         if (ret != 0) return ret;
153
154         req_data->type         = FRESCAN_REQ_NEG;
155         req_data->req          = req;
156         req_data->contract     = (frescan_contract_t *)contract;
157         req_data->request_node = the_networks[net].local_node;
158         req_data->net          = net;
159
160         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
161         if (ret != 0) return ret;
162
163         // NOTE: we preallocate a server for the negotiation process
164         server_params.values.budget = contract->min_values.budget;
165         server_params.values.period = contract->min_values.period;
166         server_params.prio          = contract->prio;
167
168         ret = frescan_servers_create(net, &server_params, &req_data->ss);
169         if (ret != 0) return ret;
170
171         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
172
173         ret = frescan_requests_enqueue(req);
174         if (ret != 0) return ret;
175
176         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
177
178         ret = frescan_bwres_robjs_wait(req_data->robj);
179         if (ret != 0) return ret;
180
181         ret = frescan_bwres_robjs_free(req_data->robj);
182         if (ret != 0) return ret;
183
184         switch (req_data->return_value) {
185         case FRESCAN_REQ_ACCEPTED:
186                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
187                 *accepted = true;
188                 *ss = req_data->ss;
189                 server_params.prio = req_data->final_values.server_prio;
190                 ret = frescan_servers_update(net, &server_params, *ss);
191                 if (ret != 0) return ret;
192                 break;
193
194         case FRESCAN_REQ_NOT_ACCEPTED:
195                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
196                 *accepted = false;
197                 ret = frescan_servers_destroy(net, req_data->ss);
198                 if (ret != 0) return ret;
199                 break;
200
201         default:
202                 ERROR("return_value unknown\n");
203                 return -1;
204         }
205
206         frescan_requests_free(req);
207         return 0;
208 }
209
210 /**
211  * frescan_bwres_renegotiate()
212  */
213
214 int frescan_bwres_renegotiate(frescan_network_t net,
215                               const frescan_contract_t *contract,
216                               frescan_ss_t ss,
217                               bool *accepted)
218 {
219         int ret;
220         frescan_request_id_t   req;
221         frescan_request_data_t *req_data;
222         frescan_server_params_t server_params;
223
224         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing renegotiation request\n");
225
226         ret = frescan_requests_alloc(&req);
227         if (ret != 0) return ret;
228
229         ret = frescan_requests_get_data(req, &req_data);
230         if (ret != 0) return ret;
231
232         req_data->type         = FRESCAN_REQ_RENEG;
233         req_data->req          = req;
234         req_data->contract     = (frescan_contract_t *)contract;
235         req_data->request_node = the_networks[net].local_node;
236         req_data->net          = net;
237         req_data->ss           = ss;
238
239         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
240         if (ret != 0) return ret;
241
242         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue renegotiation request\n");
243
244         ret = frescan_requests_enqueue(req);
245         if (ret != 0) return ret;
246
247         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
248
249         ret = frescan_bwres_robjs_wait(req_data->robj);
250         if (ret != 0) return ret;
251
252         ret = frescan_bwres_robjs_free(req_data->robj);
253         if (ret != 0) return ret;
254
255         switch (req_data->return_value) {
256         case FRESCAN_REQ_ACCEPTED:
257                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "renegotiation OK\n");
258                 *accepted = true;
259                 server_params.values.budget = contract->min_values.budget;
260                 server_params.values.period = contract->min_values.period;
261                 server_params.prio = req_data->final_values.server_prio;
262                 ret = frescan_servers_update(net, &server_params, ss);
263                 if (ret != 0) return ret;
264                 break;
265
266         case FRESCAN_REQ_NOT_ACCEPTED:
267                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
268                 *accepted = false;
269                 if (ret != 0) return ret;
270                 break;
271
272         default:
273                 ERROR("return_value unknown\n");
274                 return -1;
275         }
276
277         frescan_requests_free(req);
278         return 0;
279 }
280
281 /**
282  * frescan_bwres_cancel()
283  */
284
285 int frescan_bwres_cancel(frescan_network_t net,
286                          frescan_ss_t      ss)
287 {
288         int ret;
289         frescan_request_id_t   req;
290         frescan_request_data_t *req_data;
291
292         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing cancel request\n");
293
294         ret = frescan_requests_alloc(&req);
295         if (ret != 0) return ret;
296
297         ret = frescan_requests_get_data(req, &req_data);
298         if (ret != 0) return ret;
299
300         req_data->type         = FRESCAN_REQ_CANCEL;
301         req_data->req          = req;
302         req_data->request_node = the_networks[net].local_node;
303         req_data->net          = net;
304         req_data->ss           = ss;
305
306         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
307         if (ret != 0) return ret;
308
309         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue cancel request\n");
310
311         ret = frescan_requests_enqueue(req);
312         if (ret != 0) return ret;
313
314         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a signal\n");
315
316         ret = frescan_bwres_robjs_wait(req_data->robj);
317         if (ret != 0) return ret;
318
319         ret = frescan_bwres_robjs_free(req_data->robj);
320         if (ret != 0) return ret;
321
322         ret = frescan_servers_destroy(net, ss);
323         if (ret != 0) return ret;
324
325         frescan_requests_free(req);
326         return 0;
327 }