]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres.c
a69de0481046edf146523f5e42caf5f0c1cb54a5
[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  */
16
17 #include "frescan_bwres.h"
18 #include "frescan_data.h"
19 #include "frescan_requests.h"    // frescan_requests_init
20 #include "frescan_debug.h"
21 #include "frescan_config.h"
22 #include "frescan_servers.h"
23 #include "frescan_bwres_messages.h"
24 #include "frescan_bwres_threads.h"
25
26 /**
27  * frescan_bwres_init()
28  *
29  * Init the frescan bandwidth reservation layer
30  */
31
32 int frescan_bwres_init(frescan_network_t net)
33 {
34         int ret;
35         frescan_server_params_t params;
36
37         // TODO: server params must be configurable
38         params.values.budget = 5;
39         params.values.period.tv_sec = 1;
40         params.values.period.tv_nsec = 0;
41         params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
42
43         ret = frescan_servers_create(net, &params,
44                                      &the_networks[net].neg_messages_ss_id);
45         if (ret != 0) {
46                 ERROR("could not create server for negotiation messages\n");
47                 return ret;
48         }
49
50         ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
51         if (ret != 0) {
52                 ERROR("could not initialize the requests\n");
53                 return ret;
54         }
55
56         if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
57                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "i am master node (%u)\n",
58                       the_networks[net].local_node);
59                 ret = frescan_master_neg_thread_create(net);
60                 if (ret != 0) {
61                         ERROR("could not initialize the negotiator thread\n");
62                         return ret;
63                 }
64         } else {
65                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "i am a slave node (%u)\n",
66                       the_networks[net].local_node);
67         }
68
69         ret = frescan_acceptor_thread_create(net);
70         if (ret != 0) {
71                 ERROR("could not create acceptor thread\n");
72                 return ret;
73         }
74
75         return 0;
76 }
77
78 /**
79  * frescan_bwres_negotiate()
80  *
81  * negotiate a contract. For that we allocate a reply object and then
82  * we enqueue our request in the master's requests queue (if we are in
83  * the master node) or send it to the master through the network.
84  */
85
86 int frescan_bwres_negotiate(frescan_network_t net,
87                             const frescan_contract_t *contract,
88                             frescan_ss_t *id)
89 {
90         int ret;
91         frescan_robj_id_t reply;
92         frescan_request_id_t request;
93         frescan_neg_return_info_t return_info;
94         uint8_t msg[200];
95         int size;
96         frescan_send_params_t params;
97
98         ret = frescan_replyobject_alloc(&reply, FRESCAN_BWRES_MX_PRIO);
99         if (ret != 0) {
100                 ERROR("could not allocate reply object\n");
101                 return ret;
102         }
103
104         ret = frescan_request_alloc(&request);
105         if (ret != 0) {
106                 ERROR("could not allocate request\n");
107                 return ret;
108         }
109
110         ret = frescan_request_set_return_info(request,
111                                               (void *) &return_info);
112         if (ret != 0) {
113                 ERROR("could not set return_info pointer\n");
114                 return ret;
115         }
116
117         ret = frescan_request_set_reply(request, reply);
118         if (ret != 0) {
119                 ERROR("could not set reply\n");
120                 return ret;
121         }
122
123         if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
124                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
125                       "I am master, negotiation in local node\n");
126
127                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
128                       "set FRESCAN_NEGOTIATE type: %d\n", FRESCAN_NEGOTIATE);
129
130                 ret = frescan_request_set_type(request, FRESCAN_NEGOTIATE);
131                 if (ret != 0) {
132                         ERROR("could not set type\n");
133                         return ret;
134                 }
135
136                 ret = frescan_request_set_contract(request, contract);
137                 if (ret != 0) {
138                         ERROR("could not set contract\n");
139                         return ret;
140                 }
141
142                 ret = frescan_request_set_src(request, FRESCAN_NEG_MASTER_NODE);
143                 if (ret != 0) {
144                         ERROR("could not set src\n");
145                         return ret;
146                 }
147
148                 ret = frescan_requestqueue_enqueue(request);
149                 if (ret != 0) {
150                         ERROR("could not enqueue the request\n");
151                         return ret;
152                 }
153         } else {
154                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
155                       "I am slave, negotiation in master node\n");
156
157                 size = frescan_neg_message_create(msg, request, contract);
158
159                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
160                       "created a neg message, size: %d\n", size);
161
162                 params.net = net;
163                 params.to  = FRESCAN_NEG_MASTER_NODE;
164                 params.channel = FRESCAN_NEG_CHANNEL;
165
166                 // NOTE: if we sent the negotiation msgs with fp:
167                 // params.flags = FRESCAN_FP | FRESCAN_ASYNC;
168                 // params.prio = 8;
169
170                 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
171                 params.ss = the_networks[net].neg_messages_ss_id;
172
173                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
174                       "send msg to master, net:%u to:%u ss:%u\n",
175                       params.net, params.to, params.ss);
176
177                 ret = frescan_send(&params, msg, size);
178                 if (ret != 0) {
179                         ERROR("error while sending neg request to master\n");
180                         return ret;
181                 }
182         }
183
184         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait on reply object\n");
185
186         ret = frescan_replyobject_wait(reply);
187         if (ret != 0) {
188                 ERROR("error while waiting on the reply object\n");
189                 return ret;
190         }
191
192         ret = frescan_replyobject_free(reply);
193         if (ret != 0) {
194                 ERROR("could not free reply object\n");
195                 return ret;
196         }
197
198         if (return_info.error) {
199                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
200                       "negotiation was not accepted, error:%d\n",
201                       return_info.error);
202         } else {
203                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
204                       "negotiation finished succesfully ss:%d\n",
205                       return_info.id);
206         }
207
208         *id = return_info.id;
209
210         ret = frescan_request_free(request);
211         if (ret != 0) {
212                 ERROR("could not free request\n");
213                 return ret;
214         }
215
216         return return_info.error;
217 }
218
219 /**
220  * frescan_bwres_renegotiate()
221  *
222  * renegotiate a contract. For that we allocate a reply object and then
223  * we enqueue our request in the master's requests queue (if we are in
224  * the master node) or send it to the master through the network.
225  */
226
227 int frescan_bwres_renegotiate(frescan_network_t net,
228                               const frescan_contract_t *contract,
229                               frescan_ss_t id)
230 {
231         int ret;
232         frescan_robj_id_t reply;
233         frescan_request_id_t request;
234         frescan_neg_return_info_t return_info;
235         uint8_t msg[200];
236         int size;
237         frescan_send_params_t params;
238
239         ret = frescan_replyobject_alloc(&reply, FRESCAN_BWRES_MX_PRIO);
240         if (ret != 0) {
241                 ERROR("could not allocate reply object\n");
242                 return ret;
243         }
244
245         ret = frescan_request_alloc(&request);
246         if (ret != 0) {
247                 ERROR("could not allocate request\n");
248                 return ret;
249         }
250
251         ret = frescan_request_set_return_info(request,
252                                               (void *) &return_info);
253         if (ret != 0) {
254                 ERROR("could not set return_info pointer\n");
255                 return ret;
256         }
257
258         ret = frescan_request_set_reply(request, reply);
259         if (ret != 0) {
260                 ERROR("could not set reply\n");
261                 return ret;
262         }
263
264         ret = frescan_request_set_ss(request, id);
265         if (ret != 0) {
266                 ERROR("could not set server id\n");
267                 return ret;
268         }
269
270         if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
271                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
272                       "I am master, renegotiation in local node\n");
273
274                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
275                       "set FRESCAN_RENEGOTIATE type: %d\n",
276                       FRESCAN_RENEGOTIATE);
277
278                 ret = frescan_request_set_type(request, FRESCAN_RENEGOTIATE);
279                 if (ret != 0) {
280                         ERROR("could not set type\n");
281                         return ret;
282                 }
283
284                 ret = frescan_request_set_contract(request, contract);
285                 if (ret != 0) {
286                         ERROR("could not set contract\n");
287                         return ret;
288                 }
289
290                 ret = frescan_request_set_src(request, FRESCAN_NEG_MASTER_NODE);
291                 if (ret != 0) {
292                         ERROR("could not set src\n");
293                         return ret;
294                 }
295
296                 ret = frescan_requestqueue_enqueue(request);
297                 if (ret != 0) {
298                         ERROR("could not enqueue the request\n");
299                         return ret;
300                 }
301         } else {
302                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
303                       "I am slave, renegotiation in master node\n");
304
305                 size = frescan_reneg_message_create(msg, request, contract);
306
307                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
308                       "created a reneg message, size: %d\n", size);
309
310                 params.net = net;
311                 params.to  = FRESCAN_NEG_MASTER_NODE;
312                 params.channel = FRESCAN_NEG_CHANNEL;
313
314                 // NOTE: if we sent the negotiation msgs with fp:
315                 // params.flags = FRESCAN_FP | FRESCAN_ASYNC;
316                 // params.prio = 8;
317
318                 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
319                 params.ss = the_networks[net].neg_messages_ss_id;
320
321                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
322                       "send msg to master, net:%u to:%u ss:%u\n",
323                       params.net, params.to, params.ss);
324
325                 ret = frescan_send(&params, msg, size);
326                 if (ret != 0) {
327                         ERROR("error while sending neg request to master\n");
328                         return ret;
329                 }
330         }
331
332         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait on reply object\n");
333
334         ret = frescan_replyobject_wait(reply);
335         if (ret != 0) {
336                 ERROR("error while waiting on the reply object\n");
337                 return ret;
338         }
339
340         ret = frescan_replyobject_free(reply);
341         if (ret != 0) {
342                 ERROR("could not free reply object\n");
343                 return ret;
344         }
345
346         if (return_info.error) {
347                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
348                       "renegotiation was not accepted, error:%d\n",
349                       return_info.error);
350         } else {
351                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
352                       "renegotiation finished succesfully for ss:%d\n",
353                       id);
354         }
355
356         ret = frescan_request_free(request);
357         if (ret != 0) {
358                 ERROR("could not free request\n");
359                 return ret;
360         }
361
362         return return_info.error;
363 }