]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_messages.c
c8c775a02d775c8449f272848101bc8f4269e032
[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         while(msg < msg_to_parse + size) {
429                 ss = *((frescan_ss_t *)msg);
430                 bytes_read = sizeof(frescan_ss_t);
431                 msg = msg + bytes_read;
432
433                 vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
434
435                 vres->mode_change_type = *((uint8_t *)msg);
436                 bytes_read = sizeof(uint8_t);
437                 msg = msg + bytes_read;
438
439                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
440                                               FRESCAN_BWRES_MC_BUDGET_DEC)) {
441                         vres->old_c = *((frsh_sa_time_t *)msg);
442                         bytes_read = sizeof(frsh_sa_time_t);
443                         msg = msg + bytes_read;
444                 }
445
446                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
447                                               FRESCAN_BWRES_MC_PERIOD_DEC)) {
448                         vres->old_t = *((frsh_sa_time_t *)msg);
449                         bytes_read = sizeof(frsh_sa_time_t);
450                         msg = msg + bytes_read;
451                 }
452
453                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
454                                               FRESCAN_BWRES_MC_PRIO_DEC)) {
455                         vres->old_p = *((frsh_sa_prio_t *)msg);
456                         bytes_read = sizeof(frsh_sa_prio_t);
457                         msg = msg + bytes_read;
458                 }
459
460                 if (vres->mode_change_type != 0) {
461                         list_add_tail(&(vres->mode_change_list),
462                                       &(frescan_data[data->net].
463                                                       mode_change_list[me]));
464                 }
465
466                 data->mode_change_type |= vres->mode_change_type;
467
468                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
469                       "mc:0x%X ss:%d vres->ss:%d c:%d t:%d p:%d\n",
470                       vres->mode_change_type, ss, vres->ss,
471                       vres->old_c, vres->old_t, vres->old_p);
472         }
473
474         return 0;
475 }
476
477 /**
478  *  FRESCAN_BWRES_REP_GN
479  *  ====================
480  *  This message is sent from the MASTER to a slave as a reply to a
481  *  FRESCAN_BWRES_REQ_GN message
482  */
483
484 static int frescan_request_to_rep_gn_message
485                         (const frescan_bwres_request_data_t *data,
486                          uint8_t *msg,
487                          size_t  *size)
488 {
489         int i;
490         uint8_t *msg_begin;
491         size_t bytes_written;
492         frescan_bwres_vres_t *vres;
493
494         msg_begin = msg;
495
496         // type
497         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
498         bytes_written = sizeof(uint8_t);
499         msg = msg + bytes_written;
500
501         // req
502         *((frescan_bwres_request_id_t *)msg) = data->req;
503         bytes_written = sizeof(frescan_bwres_request_id_t);
504         msg = msg + bytes_written;
505
506         // return value
507         *((uint8_t *)msg) = data->return_value;
508         bytes_written = sizeof(uint8_t);
509         msg = msg + bytes_written;
510
511         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
512               "req:%d return:%s\n", data->req,
513                (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
514
515         if (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
516                 // new ss values
517                 for(i=0; i<data->contracts_to_neg->size; i++) {
518                         // SS
519                         *((uint16_t *)msg) = data->ss_new->ss[i];
520                         bytes_written = sizeof(uint16_t);
521                         msg = msg + bytes_written;
522
523                         // B - T - P
524                         vres = &frescan_data[data->net].scenario.
525                                                 vres_pool[data->request_node]
526                                                          [data->ss_new->ss[i]];
527
528                         *((frsh_sa_time_t *)msg) = vres->old_c;
529                         bytes_written = sizeof(frsh_sa_time_t);
530                         msg = msg + bytes_written;
531
532                         *((frsh_sa_time_t *)msg) = vres->old_t;
533                         bytes_written = sizeof(frsh_sa_time_t);
534                         msg = msg + bytes_written;
535
536                         *((frsh_sa_prio_t *)msg) = vres->old_p;
537                         bytes_written = sizeof(frsh_sa_prio_t);
538                         msg = msg + bytes_written;
539
540                         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
541                               "ss[%d]:%u b:%d t:%d p:%d\n",
542                               i, data->ss_new->ss[i],
543                               vres->old_c, vres->old_t, vres->old_p);
544                 }
545         }
546
547         *size = msg - msg_begin;
548
549         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
550
551         return 0;
552 }
553
554 static int frescan_rep_gn_message_to_request
555                                         (const uint8_t *msg_to_parse,
556                                          frescan_bwres_request_data_t *data,
557                                          size_t size)
558 {
559         int ret;
560         uint8_t *msg;
561         size_t bytes_read;
562         frescan_ss_t ss;
563         frescan_server_params_t server_params;
564         frescan_bwres_vres_t *vres;
565         frescan_node_t me;
566
567         me = frescan_data[data->net].local_node;
568
569         msg = (uint8_t *)msg_to_parse;
570
571         // req
572         data->req = *((frescan_bwres_request_id_t *)msg);
573         bytes_read = sizeof(frescan_bwres_request_id_t);
574         msg = msg + bytes_read;
575
576         // return_value
577         data->return_value = *((uint8_t *)msg);
578         bytes_read = sizeof(uint8_t);
579         msg = msg + bytes_read;
580
581         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
582               "req:%d return:%s\n", data->req,
583               (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED)?"OK":"FAIL");
584
585         if (data->return_value != FRESCAN_BWRES_REQ_ACCEPTED) return 0;
586
587         // create the new sporadic servers
588         data->ss_new->size = 0;
589
590         while(msg < msg_to_parse + size) {
591                 // SS
592                 data->ss_new->ss[data->ss_new->size] = *((uint16_t *)msg);
593                 bytes_read = sizeof(uint16_t);
594                 msg = msg + bytes_read;
595
596                 // Set values in the scenario (for mode changes)
597                 vres = &frescan_data[data->net].scenario.vres_pool[me]
598                                 [data->ss_new->ss[data->ss_new->size]];
599
600                 vres->ss       = data->ss_new->ss[data->ss_new->size];
601                 vres->node     = me;
602
603                 // Budget
604                 vres->old_c    = *((frsh_sa_time_t *)msg);
605                 bytes_read = sizeof(frsh_sa_time_t);
606                 msg = msg + bytes_read;
607
608                 // Period
609                 vres->old_t    = *((frsh_sa_time_t *)msg);
610                 bytes_read = sizeof(frsh_sa_time_t);
611                 msg = msg + bytes_read;
612
613                 // Prio
614                 vres->old_p    = *((frsh_sa_prio_t *)msg);
615                 bytes_read = sizeof(frsh_sa_prio_t);
616                 msg = msg + bytes_read;
617
618                 // Create server
619                 server_params.budget = frsh_rel_time_to_usec
620                                 (frsh_sa_time_to_rel_time(vres->old_c)) /
621                                 FRESCAN_FRAME_TX_TIME_US;
622                 server_params.period = frsh_sa_time_to_rel_time(vres->old_t);
623                 server_params.prio = vres->old_p;
624
625                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
626                       "ss_master[%d]:%u ss[%d]:%u b:%d t:%d p:%d\n",
627                       data->ss_new->size, data->ss_new->ss[data->ss_new->size],
628                       data->ss_new->size, ss,
629                       vres->old_c, vres->old_t, vres->old_p);
630
631                 DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
632                       "server_params[%d] b:%d t:(%d,%d) p:%d\n",
633                       data->ss_new->size, server_params.budget,
634                       server_params.period.tv_sec,
635                       server_params.period.tv_nsec,
636                       server_params.prio);
637
638                 ret = frescan_servers_create(data->net, &server_params, &ss);
639                 if (ret != 0) return ret;
640
641                 if (ss != data->ss_new->ss[data->ss_new->size]) {
642                         FRESCAN_ERROR("ss from master != ss created\n");
643                         return -1;
644                 }
645
646                 data->ss_new->size++;
647         }
648
649         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
650               "data->ss_new->size:%u\n", data->ss_new->size);
651
652         return 0;
653 }
654
655 /**
656  * frescan_messages_send_request()
657  *
658  * this function converts a request with the necessary data into a message
659  * and sends it.
660  *
661  * @req_data: the request to be sent (NOTE: the network is in req_data)
662  *
663  */
664
665 int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
666 {
667         int ret;
668         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
669         size_t size;
670
671         switch(req_data->type) {
672                 case FRESCAN_BWRES_REQ_GN:
673                         ret = frescan_request_to_gn_message
674                                                         (req_data, msg, &size);
675                         if (ret != 0) return ret;
676                         send_params[req_data->net].to =
677                                                 FRESCAN_BWRES_MASTER_NODE;
678                         break;
679                 case FRESCAN_BWRES_REQ_MC:
680                         ret = frescan_request_to_mc_message
681                                                         (req_data, msg, &size);
682                         if (ret != 0) return ret;
683                         send_params[req_data->net].to = req_data->request_node;
684                         break;
685                 case FRESCAN_BWRES_REP_GN:
686                         ret = frescan_request_to_rep_gn_message
687                                                         (req_data, msg, &size);
688                         if (ret != 0) return ret;
689                         send_params[req_data->net].to = req_data->request_node;
690                         break;
691                 case FRESCAN_BWRES_REQ_RES:
692                 case FRESCAN_BWRES_REQ_RES_GET:
693                 case FRESCAN_BWRES_REP_RES_GET:
694                 case FRESCAN_BWRES_REQ_RES_SET:
695                 case FRESCAN_BWRES_REQ_RES_COMMIT:
696                 case FRESCAN_BWRES_REQ_RES_CANCEL:
697                 default:
698                         FRESCAN_ERROR("request type not supported\n");
699                         return -1;
700         }
701
702         ret = frescan_send(&send_params[req_data->net], msg, size);
703         if (ret != 0) return ret;
704
705         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
706               "sent request, type:%X size:%u\n",
707               req_data->type, size);
708
709         return 0;
710 }
711
712 /**
713  * frescan_messages_recv_request()
714  *
715  * this function BLOCKS the calling thread until receives a message
716  * and transforms it into a request.
717  *
718  * @req_data: the request data to fill from the message bytes (out)
719  *
720  */
721
722 int frescan_messages_recv_request(frescan_network_t    net,
723                                   frescan_bwres_request_id_t *req)
724 {
725         int ret;
726         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
727         uint8_t *msg_to_parse;
728         size_t recv_bytes;
729         frescan_node_t from;
730         frescan_prio_t prio;
731         frescan_bwres_request_data_t *req_data;
732
733         ret = frescan_bwres_requests_alloc(req);
734         if (ret != 0) return ret;
735
736         ret = frescan_bwres_requests_get_data(*req, &req_data);
737         if (ret != 0) return ret;
738
739         ret = frescan_recv(&recv_params[net],
740                             msg,
741                             sizeof(msg),
742                             &recv_bytes,
743                             &from,
744                             &prio);
745         if (ret != 0) return ret;
746
747         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
748               "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
749               from, recv_bytes, prio, recv_params[net].channel,
750               recv_params[net].flags);
751
752         req_data->request_node = from;
753         req_data->net          = net;
754         req_data->type         = *((uint8_t *)msg);
755
756         msg_to_parse = msg + sizeof(uint8_t);
757         recv_bytes   = recv_bytes - sizeof(uint8_t);
758
759         switch(req_data->type) {
760                 case FRESCAN_BWRES_REQ_GN:
761                         return frescan_gn_message_to_request(msg_to_parse,
762                                                              req_data,
763                                                              recv_bytes);
764                 case FRESCAN_BWRES_REQ_MC:
765                         return frescan_mc_message_to_request(msg_to_parse,
766                                                              req_data,
767                                                              recv_bytes);
768                 case FRESCAN_BWRES_REP_GN:
769                         return frescan_rep_gn_message_to_request(msg_to_parse,
770                                                                  req_data,
771                                                                  recv_bytes);
772                 case FRESCAN_BWRES_REQ_RES:
773                 case FRESCAN_BWRES_REQ_RES_GET:
774                 case FRESCAN_BWRES_REP_RES_GET:
775                 case FRESCAN_BWRES_REQ_RES_SET:
776                 case FRESCAN_BWRES_REQ_RES_COMMIT:
777                 case FRESCAN_BWRES_REQ_RES_CANCEL:
778                 default:
779                         FRESCAN_ERROR("request type %d not supported\n",
780                                       req_data->type);
781                         return -1;
782         }
783 }