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