]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_messages.c
debugging messages
[frescor/fna.git] / src_frescan / frescan_bwres_messages.c
1 /*!
2  * @file frescan_bwres_messages.c
3  *
4  * @brief FRESCAN bandwidth reservation layer: negotiation messages formating
5  *
6  * This module contains the data types that define the FRESCAN negotiation
7  * message format and operations to convert them into or from negotiation
8  * requests
9  *
10  * @version 0.01
11  *
12  * @date 2-Apr-2008
13  *
14  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
15  *
16  * @license
17  *
18  * -----------------------------------------------------------------------
19  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
20  *
21  *    Universidad de Cantabria,              SPAIN
22  *    University of York,                    UK
23  *    Scuola Superiore Sant'Anna,            ITALY
24  *    Kaiserslautern University,             GERMANY
25  *    Univ. Politécnica  Valencia,           SPAIN
26  *    Czech Technical University in Prague,  CZECH REPUBLIC
27  *    ENEA                                   SWEDEN
28  *    Thales Communication S.A.              FRANCE
29  *    Visual Tools S.A.                      SPAIN
30  *    Rapita Systems Ltd                     UK
31  *    Evidence                               ITALY
32  *
33  *    See http://www.frescor.org for a link to partners' websites
34  *
35  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
36  *        in part by the European Union Sixth Framework Programme
37  *        The European Union is not liable of any use that may be
38  *        made of this code.
39  *
40  *  This file is part of FRESCAN
41  *
42  *  FRESCAN is free software; you can  redistribute it and/or  modify
43  *  it under the terms of  the GNU General Public License as published by
44  *  the Free Software Foundation;  either  version 2, or (at  your option)
45  *  any later version.
46  *
47  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
48  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
49  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
50  *  General Public License for more details.
51  *
52  *  You should have  received a  copy of  the  GNU  General Public License
53  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
54  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
55  *  02111-1307, USA.
56  *
57  * As a special exception, including FRESCAN header files in a file,
58  * instantiating FRESCAN generics or templates, or linking other files
59  * with FRESCAN objects to produce an executable application, does not
60  * by itself cause the resulting executable application to be covered
61  * by the GNU General Public License. This exception does not
62  * however invalidate any other reasons why the executable file might be
63  * covered by the GNU Public License.
64  * -----------------------------------------------------------------------
65  *
66  */
67
68 #include <string.h>
69 #include "frescan_bwres_messages.h"
70 #include "frescan_bwres_requests.h"
71 #include "frescan.h"
72 #include "frescan_servers.h"
73 #include "frescan_data.h"
74 #include "frescan_config.h"
75 #include "frescan_debug.h"
76 #include "frsh_distributed.h"
77
78 #define FRESCAN_BWRES_MX_MSG_SIZE 5000  // TODO: adjust to the accurate value
79
80 /**
81  * frescan_messages_init()
82  */
83
84 static frescan_send_params_t send_params[FRESCAN_MX_NETWORKS];
85 static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
86
87 int frescan_messages_init(frescan_network_t net)
88 {
89         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "initialization\n");
90
91         send_params[net].net     = net;
92         send_params[net].channel = FRESCAN_BWRES_NEG_MSG_CHAN;
93         send_params[net].flags   = FRESCAN_SS | FRESCAN_ASYNC;
94         send_params[net].ss      = frescan_data[net].neg_messages_ss_id;
95         send_params[net].to      = FRESCAN_BWRES_MASTER_NODE;
96
97         recv_params[net].net     = net;
98         recv_params[net].channel = FRESCAN_BWRES_NEG_MSG_CHAN;
99         recv_params[net].flags   = FRESCAN_SYNC;
100
101         return 0;
102 }
103
104 /**
105  *  FRESCAN_BWRES_REQ_GN
106  *  ====================
107  *  This message is sent from a SLAVE to the MASTER when the slave wants
108  *  to make a negotiation (including creating new vres, renegotiations and
109  *  cancellations).
110  */
111
112 static int frescan_request_to_gn_message
113                                 (const frescan_bwres_request_data_t *data,
114                                  uint8_t *msg,
115                                  size_t  *size)
116 {
117         int ret, i;
118         uint8_t *msg_begin, *msg_tmp;
119         size_t bytes_written;
120
121         msg_begin = msg;
122
123         // type: FRESCAN_GN_MESSAGE
124         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_GN;
125         bytes_written = sizeof(uint8_t);
126         msg = msg + bytes_written;
127
128         // req
129         *((frescan_bwres_request_id_t *)msg) = data->req;
130         bytes_written = sizeof(frescan_bwres_request_id_t);
131         msg = msg + bytes_written;
132
133         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
134               "GN message req:%u\n", data->req);
135
136         // NEG-GROUP
137         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
138               "NEG-GROUP num contracts:%d\n", data->contracts_to_neg->size);
139
140         *((uint8_t *)msg) = (uint8_t)data->contracts_to_neg->size;
141         bytes_written = sizeof(uint8_t);
142         msg = msg + bytes_written;
143
144         for (i=0; i<data->contracts_to_neg->size; i++) {
145                 // reserve 2 bytes for the size of the marshalled contract
146                 msg_tmp = msg;
147                 msg     = msg + sizeof(uint16_t);
148                 // marshal the contract
149                 ret = frsh_contract_marshal
150                                 (&data->contracts_to_neg->contracts[i],
151                                  msg,
152                                  FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
153                                  &bytes_written);
154                 if (ret != 0) {
155                         FRESCAN_ERROR("frsh_contract_marshal return -1\n");
156                         return -1;
157                 }
158                 // write the size and update the message pointer msg
159                 *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
160                 msg = msg + bytes_written;
161
162                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
163                       "contract[%d].size:%u\n", i, bytes_written);
164         }
165
166         // RENEG-GROUP
167         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
168               "RENEG-GROUP num contracts:%d\n",data->contracts_to_reneg->size);
169
170         *((uint8_t *)msg) = (uint8_t)data->contracts_to_reneg->size;
171         bytes_written = sizeof(uint8_t);
172         msg = msg + bytes_written;
173
174         for (i=0; i<data->contracts_to_reneg->size; i++) {
175                 // write the ss
176                 *((uint16_t *)msg) = (uint16_t)data->ss_to_reneg->ss[i];
177                 bytes_written = sizeof(uint16_t);
178                 msg = msg + bytes_written;
179                 // reserve 2 bytes for the size of the marshalled contract
180                 msg_tmp = msg;
181                 msg     = msg + sizeof(uint16_t);
182                 // marshal the contract
183                 ret = frsh_contract_marshal
184                                 (&data->contracts_to_reneg->contracts[i],
185                                  msg,
186                                  FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
187                                  &bytes_written);
188                 if (ret != 0) {
189                         FRESCAN_ERROR("frsh_contract_marshal return -1\n");
190                         return -1;
191                 }
192                 // write the size and update the message pointer msg
193                 *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
194                 msg = msg + bytes_written;
195
196                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
197                       "contract[%d].size:%u ss[%d]:%u\n",
198                       i, bytes_written, i, data->ss_to_reneg->ss[i]);
199         }
200
201         // CANCEL-GROUP
202         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "CANCEL-GROUP num ss:%d\n",
203               data->ss_to_cancel->size);
204
205         *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
206         bytes_written = sizeof(uint8_t);
207         msg = msg + bytes_written;
208
209         for (i=0; i<data->ss_to_cancel->size; i++) {
210                 // write the ss
211                 *((uint16_t *)msg) = (uint16_t)data->ss_to_cancel->ss[i];
212                 bytes_written = sizeof(uint16_t);
213                 msg = msg + bytes_written;
214
215                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
216                       "ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
217         }
218
219         *size = msg - msg_begin;
220
221         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
222
223         return 0;
224 }
225
226 static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
227                                          frescan_bwres_request_data_t *data,
228                                          size_t size)
229 {
230         int ret, i;
231         uint8_t *msg;
232         size_t bytes_read, contract_size;
233
234         msg = (uint8_t *)msg_to_parse;
235
236         data->contracts_to_neg   = &data->contracts_to_neg_data;
237         data->contracts_to_reneg = &data->contracts_to_reneg_data;
238         data->ss_to_reneg        = &data->ss_to_reneg_data;
239         data->ss_to_cancel       = &data->ss_to_cancel_data;
240         data->ss_new             = &data->ss_new_data;
241
242         // req
243         data->req = *((frescan_bwres_request_id_t *)msg);
244         bytes_read = sizeof(frescan_bwres_request_id_t);
245         msg = msg + bytes_read;
246
247         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
248               "GN message req:%u\n", data->req);
249
250         // NEG-GROUP
251         data->contracts_to_neg->size = *((uint8_t *)msg);
252         bytes_read = sizeof(uint8_t);
253         msg = msg + bytes_read;
254
255         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
256               "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
257
258         for (i=0; i<data->contracts_to_neg->size; i++) {
259                 contract_size = *((uint16_t *)msg);
260                 bytes_read = sizeof(uint16_t);
261                 msg = msg + bytes_read;
262
263                 // unmarshal the contract
264                 ret = frsh_contract_unmarshal
265                                 (&data->contracts_to_neg->contracts[i],
266                                  msg,
267                                  contract_size);
268                 if (ret != 0) {
269                         FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
270                         return -1;
271                 }
272
273                 bytes_read = contract_size;
274                 msg = msg + bytes_read;
275
276                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
277                       "contract[%d].size:%u\n", i, contract_size);
278         }
279
280          // RENEG-GROUP
281         data->contracts_to_reneg->size = *((uint8_t *)msg);
282         bytes_read = sizeof(uint8_t);
283         msg = msg + bytes_read;
284
285         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
286               "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
287
288         for (i=0; i<data->contracts_to_reneg->size; i++) {
289                 data->ss_to_reneg->ss[i] = *((uint16_t *)msg);
290                 bytes_read = sizeof(uint16_t);
291                 msg = msg + bytes_read;
292
293                 contract_size = *((uint16_t *)msg);
294                 bytes_read = sizeof(uint16_t);
295                 msg = msg + bytes_read;
296
297                 // unmarshal the contract
298                 ret = frsh_contract_unmarshal
299                                 (&data->contracts_to_reneg->contracts[i],
300                                  msg,
301                                  contract_size);
302                 if (ret != 0) {
303                         FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
304                         return -1;
305                 }
306
307                 bytes_read = contract_size;
308                 msg = msg + bytes_read;
309
310                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
311                       "contract[%d].size:%u ss[%d]:%u\n",
312                       i, contract_size, i, data->ss_to_reneg->ss[i]);
313         }
314
315         // CANCEL-GROUP
316         data->ss_to_cancel->size = *((uint8_t *)msg);
317         bytes_read = sizeof(uint8_t);
318         msg = msg + bytes_read;
319
320         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
321               "CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
322
323         for (i=0; i<data->ss_to_cancel->size; i++) {
324                 // write the ss
325                 data->ss_to_cancel->ss[i] = *((uint16_t *)msg);
326                 bytes_read = sizeof(uint16_t);
327                 msg = msg + bytes_read;
328
329                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
330                       "ss[%d]:%u\n", i, data->ss_to_cancel->ss[i]);
331         }
332
333         return 0;
334 }
335
336 /**
337  *  FRESCAN_BWRES_REQ_MC
338  *  ====================
339  *  This message is sent from the MASTER to a slave when there is a change
340  *  in the budget value assigned by the spare capacity algorithm.
341  */
342
343 static int frescan_request_to_mc_message
344                                 (const frescan_bwres_request_data_t *data,
345                                  uint8_t *msg,
346                                  size_t  *size)
347 {
348         frescan_bwres_vres_t *vres;
349         uint8_t *msg_begin;
350         size_t bytes_written;
351
352         msg_begin = msg;
353
354         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
355               "MC send mode_change_type:0x%X\n", data->mode_change_type);
356
357         // type: FRESCAN_GN_MESSAGE
358         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_MC;
359         bytes_written = sizeof(uint8_t);
360         msg = msg + bytes_written;
361
362         // write the SS-mode_change_type-values fields
363         list_for_each_entry(vres,
364                             &frescan_data[data->net].mode_change_list
365                                                         [data->request_node],
366                             mode_change_list)
367         {
368                 if ((vres->mode_change_type & data->mode_change_type) !=
369                      data->mode_change_type) continue;
370
371                 *((frescan_ss_t *)msg) = vres->ss;
372                 bytes_written = sizeof(frescan_ss_t);
373                 msg = msg + bytes_written;
374
375                 *((uint8_t *)msg) = (uint8_t)data->mode_change_type;
376                 bytes_written = sizeof(uint8_t);
377                 msg = msg + bytes_written;
378
379                 if (data->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
380                                               FRESCAN_BWRES_MC_BUDGET_DEC)) {
381                         *((frsh_sa_time_t *)msg) = vres->old_c;
382                         bytes_written = sizeof(frsh_sa_time_t);
383                         msg = msg + bytes_written;
384                 }
385
386                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
387                                               FRESCAN_BWRES_MC_PERIOD_DEC)) {
388                         *((frsh_sa_time_t *)msg) = vres->old_t;
389                         bytes_written = sizeof(frsh_sa_time_t);
390                         msg = msg + bytes_written;
391                 }
392
393                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
394                                               FRESCAN_BWRES_MC_PRIO_DEC)) {
395                         *((frsh_sa_prio_t *)msg) = vres->old_p;
396                         bytes_written = sizeof(frsh_sa_prio_t);
397                         msg = msg + bytes_written;
398                 }
399
400                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
401                       "ss:%d c:%d t:%d p:%d\n",
402                       vres->ss, vres->old_c, vres->old_t, vres->old_p);
403         }
404
405         *size = msg - msg_begin;
406
407         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
408
409         return 0;
410 }
411
412 static int frescan_mc_message_to_request(const uint8_t *msg_to_parse,
413                                          frescan_bwres_request_data_t *data,
414                                          size_t size)
415 {
416         uint8_t *msg;
417         size_t bytes_read;
418         frescan_ss_t ss;
419         frescan_bwres_vres_t *vres;
420         frescan_node_t me;
421
422         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "MC message received\n");
423
424         msg = (uint8_t *)msg_to_parse;
425         me = frescan_data[data->net].local_node;
426         data->mode_change_type = 0;
427
428         INIT_LIST_HEAD(&frescan_data[data->net].mode_change_list[me]);
429
430         while(msg < msg_to_parse + size) {
431                 ss = *((frescan_ss_t *)msg);
432                 bytes_read = sizeof(frescan_ss_t);
433                 msg = msg + bytes_read;
434
435                 vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
436
437                 vres->mode_change_type = *((uint8_t *)msg);
438                 bytes_read = sizeof(uint8_t);
439                 msg = msg + bytes_read;
440
441                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
442                                               FRESCAN_BWRES_MC_BUDGET_DEC)) {
443                         vres->old_c = *((frsh_sa_time_t *)msg);
444                         bytes_read = sizeof(frsh_sa_time_t);
445                         msg = msg + bytes_read;
446                 }
447
448                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
449                                               FRESCAN_BWRES_MC_PERIOD_DEC)) {
450                         vres->old_t = *((frsh_sa_time_t *)msg);
451                         bytes_read = sizeof(frsh_sa_time_t);
452                         msg = msg + bytes_read;
453                 }
454
455                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
456                                               FRESCAN_BWRES_MC_PRIO_DEC)) {
457                         vres->old_p = *((frsh_sa_prio_t *)msg);
458                         bytes_read = sizeof(frsh_sa_prio_t);
459                         msg = msg + bytes_read;
460                 }
461
462                 if (vres->mode_change_type != 0) {
463                         list_add_tail(&(vres->mode_change_list),
464                                       &(frescan_data[data->net].
465                                                       mode_change_list[me]));
466                 }
467
468                 data->mode_change_type |= vres->mode_change_type;
469
470                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
471                       "mc:0x%X ss:%d vres->ss:%d c:%d t:%d p:%d\n",
472                       vres->mode_change_type, ss, vres->ss,
473                       vres->old_c, vres->old_t, vres->old_p);
474         }
475
476         return 0;
477 }
478
479 /**
480  *  FRESCAN_BWRES_REP_GN
481  *  ====================
482  *  This message is sent from the MASTER to a slave as a reply to a
483  *  FRESCAN_BWRES_REQ_GN message
484  */
485
486 static int frescan_request_to_rep_gn_message
487                         (const frescan_bwres_request_data_t *data,
488                          uint8_t *msg,
489                          size_t  *size)
490 {
491         int i;
492         uint8_t *msg_begin;
493         size_t bytes_written;
494         frescan_bwres_vres_t *vres;
495
496         msg_begin = msg;
497
498         // type
499         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
500         bytes_written = sizeof(uint8_t);
501         msg = msg + bytes_written;
502
503         // req
504         *((frescan_bwres_request_id_t *)msg) = data->req;
505         bytes_written = sizeof(frescan_bwres_request_id_t);
506         msg = msg + bytes_written;
507
508         // return value
509         *((uint8_t *)msg) = data->return_value;
510         bytes_written = sizeof(uint8_t);
511         msg = msg + bytes_written;
512
513         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
514               "req:%d return:%s\n", data->req,
515                (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
516
517         if (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
518                 // new ss values
519                 for(i=0; i<data->contracts_to_neg->size; i++) {
520                         // SS
521                         *((uint16_t *)msg) = data->ss_new->ss[i];
522                         bytes_written = sizeof(uint16_t);
523                         msg = msg + bytes_written;
524
525                         // B - T - P
526                         vres = &frescan_data[data->net].scenario.
527                                                 vres_pool[data->request_node]
528                                                          [data->ss_new->ss[i]];
529
530                         *((frsh_sa_time_t *)msg) = vres->old_c;
531                         bytes_written = sizeof(frsh_sa_time_t);
532                         msg = msg + bytes_written;
533
534                         *((frsh_sa_time_t *)msg) = vres->old_t;
535                         bytes_written = sizeof(frsh_sa_time_t);
536                         msg = msg + bytes_written;
537
538                         *((frsh_sa_prio_t *)msg) = vres->old_p;
539                         bytes_written = sizeof(frsh_sa_prio_t);
540                         msg = msg + bytes_written;
541
542                         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
543                               "ss[%d]:%u b:%d t:%d p:%d\n",
544                               i, data->ss_new->ss[i],
545                               vres->old_c, vres->old_t, vres->old_p);
546                 }
547         }
548
549         *size = msg - msg_begin;
550
551         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
552
553         return 0;
554 }
555
556 static int frescan_rep_gn_message_to_request
557                                         (const uint8_t *msg_to_parse,
558                                          frescan_bwres_request_data_t *data,
559                                          size_t size)
560 {
561         int ret;
562         uint8_t *msg;
563         size_t bytes_read;
564         frescan_ss_t ss;
565         frescan_server_params_t server_params;
566         frescan_bwres_vres_t *vres;
567         frescan_node_t me;
568
569         me = frescan_data[data->net].local_node;
570
571         msg = (uint8_t *)msg_to_parse;
572
573         // req
574         data->req = *((frescan_bwres_request_id_t *)msg);
575         bytes_read = sizeof(frescan_bwres_request_id_t);
576         msg = msg + bytes_read;
577
578         // return_value
579         data->return_value = *((uint8_t *)msg);
580         bytes_read = sizeof(uint8_t);
581         msg = msg + bytes_read;
582
583         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
584               "req:%d return:%s\n", data->req,
585               (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
586
587         if (data->return_value != FRESCAN_BWRES_REQ_ACCEPTED) return 0;
588
589         // create the new sporadic servers
590         data->ss_new->size = 0;
591
592         while(msg < msg_to_parse + size) {
593                 // SS
594                 data->ss_new->ss[data->ss_new->size] = *((uint16_t *)msg);
595                 bytes_read = sizeof(uint16_t);
596                 msg = msg + bytes_read;
597
598                 // Set values in the scenario (for mode changes)
599                 vres = &frescan_data[data->net].scenario.vres_pool[me]
600                                 [data->ss_new->ss[data->ss_new->size]];
601
602                 vres->ss       = data->ss_new->ss[data->ss_new->size];
603                 vres->node     = me;
604
605                 // Budget
606                 vres->old_c    = *((frsh_sa_time_t *)msg);
607                 bytes_read = sizeof(frsh_sa_time_t);
608                 msg = msg + bytes_read;
609
610                 // Period
611                 vres->old_t    = *((frsh_sa_time_t *)msg);
612                 bytes_read = sizeof(frsh_sa_time_t);
613                 msg = msg + bytes_read;
614
615                 // Prio
616                 vres->old_p    = *((frsh_sa_prio_t *)msg);
617                 bytes_read = sizeof(frsh_sa_prio_t);
618                 msg = msg + bytes_read;
619
620                 // Create server
621                 server_params.budget = frsh_rel_time_to_usec
622                                 (frsh_sa_time_to_rel_time(vres->old_c)) /
623                                 FRESCAN_FRAME_TX_TIME_US;
624                 server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
625                 server_params.prio = vres->old_p;
626
627                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
628                       "ss_master[%d]:%u ss[%d]:%u b:%d t:%d p:%d\n",
629                       data->ss_new->size, data->ss_new->ss[data->ss_new->size],
630                       data->ss_new->size, ss,
631                       vres->old_c, vres->old_t, vres->old_p);
632
633                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
634                       "server_params[%d] b:%d t:(%d,%d) p:%d\n",
635                       data->ss_new->size, server_params.budget,
636                       server_params.period.tv_sec,
637                       server_params.period.tv_nsec,
638                       server_params.prio);
639
640                 ret = frescan_servers_create(data->net, &server_params, &ss);
641                 if (ret != 0) return ret;
642
643                 if (ss != data->ss_new->ss[data->ss_new->size]) {
644                         FRESCAN_ERROR("ss from master(%u) != ss created(%u)\n",
645                                       data->ss_new->ss[data->ss_new->size], ss);
646                         return -1;
647                 }
648
649                 data->ss_new->size++;
650         }
651
652         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
653               "data->ss_new->size:%u\n", data->ss_new->size);
654
655         return 0;
656 }
657
658 /**
659  * frescan_messages_send_request()
660  *
661  * this function converts a request with the necessary data into a message
662  * and sends it.
663  *
664  * @req_data: the request to be sent (NOTE: the network is in req_data)
665  *
666  */
667
668 int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
669 {
670         int ret;
671         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
672         size_t size;
673
674         switch(req_data->type) {
675                 case FRESCAN_BWRES_REQ_GN:
676                         ret = frescan_request_to_gn_message
677                                                         (req_data, msg, &size);
678                         if (ret != 0) return ret;
679                         send_params[req_data->net].to =
680                                                 FRESCAN_BWRES_MASTER_NODE;
681                         break;
682                 case FRESCAN_BWRES_REQ_MC:
683                         ret = frescan_request_to_mc_message
684                                                         (req_data, msg, &size);
685                         if (ret != 0) return ret;
686                         send_params[req_data->net].to = req_data->request_node;
687                         break;
688                 case FRESCAN_BWRES_REP_GN:
689                         ret = frescan_request_to_rep_gn_message
690                                                         (req_data, msg, &size);
691                         if (ret != 0) return ret;
692                         send_params[req_data->net].to = req_data->request_node;
693                         break;
694                 case FRESCAN_BWRES_REQ_RES:
695                 case FRESCAN_BWRES_REQ_RES_GET:
696                 case FRESCAN_BWRES_REP_RES_GET:
697                 case FRESCAN_BWRES_REQ_RES_SET:
698                 case FRESCAN_BWRES_REQ_RES_COMMIT:
699                 case FRESCAN_BWRES_REQ_RES_CANCEL:
700                 default:
701                         FRESCAN_ERROR("request type not supported\n");
702                         return -1;
703         }
704
705         ret = frescan_send(&send_params[req_data->net], msg, size);
706         if (ret != 0) return ret;
707
708         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
709               "sent request, type:%X size:%u\n",
710               req_data->type, size);
711
712         return 0;
713 }
714
715 /**
716  * frescan_messages_recv_request()
717  *
718  * this function BLOCKS the calling thread until receives a message
719  * and transforms it into a request.
720  *
721  * @req_data: the request data to fill from the message bytes (out)
722  *
723  */
724
725 int frescan_messages_recv_request(frescan_network_t    net,
726                                   frescan_bwres_request_id_t *req)
727 {
728         int ret;
729         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
730         uint8_t *msg_to_parse;
731         size_t recv_bytes;
732         frescan_node_t from;
733         frescan_prio_t prio;
734         frescan_bwres_request_data_t *req_data;
735
736         ret = frescan_bwres_requests_alloc(req);
737         if (ret != 0) return ret;
738
739         ret = frescan_bwres_requests_get_data(*req, &req_data);
740         if (ret != 0) return ret;
741
742         ret = frescan_recv(&recv_params[net],
743                             msg,
744                             sizeof(msg),
745                             &recv_bytes,
746                             &from,
747                             &prio);
748         if (ret != 0) return ret;
749
750         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
751               "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
752               from, recv_bytes, prio, recv_params[net].channel,
753               recv_params[net].flags);
754
755         req_data->request_node = from;
756         req_data->net          = net;
757         req_data->type         = *((uint8_t *)msg);
758
759         msg_to_parse = msg + sizeof(uint8_t);
760         recv_bytes   = recv_bytes - sizeof(uint8_t);
761
762         switch(req_data->type) {
763                 case FRESCAN_BWRES_REQ_GN:
764                         return frescan_gn_message_to_request(msg_to_parse,
765                                                              req_data,
766                                                              recv_bytes);
767                 case FRESCAN_BWRES_REQ_MC:
768                         return frescan_mc_message_to_request(msg_to_parse,
769                                                              req_data,
770                                                              recv_bytes);
771                 case FRESCAN_BWRES_REP_GN:
772                         return frescan_rep_gn_message_to_request(msg_to_parse,
773                                                                  req_data,
774                                                                  recv_bytes);
775                 case FRESCAN_BWRES_REQ_RES:
776                 case FRESCAN_BWRES_REQ_RES_GET:
777                 case FRESCAN_BWRES_REP_RES_GET:
778                 case FRESCAN_BWRES_REQ_RES_SET:
779                 case FRESCAN_BWRES_REQ_RES_COMMIT:
780                 case FRESCAN_BWRES_REQ_RES_CANCEL:
781                 default:
782                         FRESCAN_ERROR("request type %d not supported\n",
783                                       req_data->type);
784                         return -1;
785         }
786 }