]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_messages.c
add get budget and period
[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", 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", 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         // type: FRESCAN_GN_MESSAGE
355         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_MC;
356         bytes_written = sizeof(uint8_t);
357         msg = msg + bytes_written;
358
359         // write the SS-mode_change_type-values fields
360         list_for_each_entry(vres,
361                             &frescan_data[data->net].mode_change_list
362                                                         [data->request_node],
363                             mode_change_list)
364         {
365                 if ((vres->mode_change_type & data->mode_change_type) !=
366                      data->mode_change_type) continue;
367
368                 *((frescan_ss_t *)msg) = vres->ss;
369                 bytes_written = sizeof(frescan_ss_t);
370                 msg = msg + bytes_written;
371
372                 *((uint8_t *)msg) = (uint8_t)data->mode_change_type;
373                 bytes_written = sizeof(uint8_t);
374                 msg = msg + bytes_written;
375
376                 if (data->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
377                                               FRESCAN_BWRES_MC_BUDGET_DEC)) {
378                         *((frsh_sa_time_t *)msg) = vres->old_c;
379                         bytes_written = sizeof(frsh_sa_time_t);
380                         msg = msg + bytes_written;
381                 }
382
383                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
384                                               FRESCAN_BWRES_MC_PERIOD_DEC)) {
385                         *((frsh_sa_time_t *)msg) = vres->old_t;
386                         bytes_written = sizeof(frsh_sa_time_t);
387                         msg = msg + bytes_written;
388                 }
389
390                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
391                                               FRESCAN_BWRES_MC_PRIO_DEC)) {
392                         *((frsh_sa_prio_t *)msg) = vres->old_p;
393                         bytes_written = sizeof(frsh_sa_prio_t);
394                         msg = msg + bytes_written;
395                 }
396         }
397
398         *size = msg - msg_begin;
399
400         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
401
402         return 0;
403 }
404
405 static int frescan_mc_message_to_request(const uint8_t *msg_to_parse,
406                                          frescan_bwres_request_data_t *data,
407                                          size_t size)
408 {
409         uint8_t *msg;
410         size_t bytes_read;
411         frescan_ss_t ss;
412         frescan_bwres_vres_t *vres;
413         frescan_node_t me;
414
415         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "MC message\n");
416
417         msg = (uint8_t *)msg_to_parse;
418         me = frescan_data[data->net].local_node;
419         data->mode_change_type = 0;
420
421         while(msg < msg_to_parse + size) {
422                 ss = *((frescan_ss_t *)msg);
423                 bytes_read = sizeof(frescan_ss_t);
424                 msg = msg + bytes_read;
425
426                 vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
427
428                 vres->mode_change_type = *((uint8_t *)msg);
429                 bytes_read = sizeof(uint8_t);
430                 msg = msg + bytes_read;
431
432                 if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
433                                               FRESCAN_BWRES_MC_BUDGET_DEC)) {
434                         vres->old_c = *((frsh_sa_time_t *)msg);
435                         bytes_read = sizeof(frsh_sa_time_t);
436                         msg = msg + bytes_read;
437                 }
438
439                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
440                                               FRESCAN_BWRES_MC_PERIOD_DEC)) {
441                         vres->old_t = *((frsh_sa_time_t *)msg);
442                         bytes_read = sizeof(frsh_sa_time_t);
443                         msg = msg + bytes_read;
444                 }
445
446                 if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
447                                               FRESCAN_BWRES_MC_PRIO_DEC)) {
448                         vres->old_p = *((frsh_sa_prio_t *)msg);
449                         bytes_read = sizeof(frsh_sa_prio_t);
450                         msg = msg + bytes_read;
451                 }
452
453                 if (vres->mode_change_type != 0) {
454                         list_add_tail(&(vres->mode_change_list),
455                                       &(frescan_data[data->net].
456                                                       mode_change_list[me]));
457                 }
458
459                 data->mode_change_type |= vres->mode_change_type;
460         }
461
462         return 0;
463 }
464
465 /**
466  *  FRESCAN_BWRES_REP_GN
467  *  ====================
468  *  This message is sent from the MASTER to a slave as a reply to a
469  *  FRESCAN_BWRES_REQ_GN message
470  */
471
472 static int frescan_request_to_rep_gn_message
473                         (const frescan_bwres_request_data_t *data,
474                          uint8_t *msg,
475                          size_t  *size)
476 {
477         int i;
478         uint8_t *msg_begin;
479         size_t bytes_written;
480         frescan_bwres_vres_t *vres;
481
482         msg_begin = msg;
483
484         // type
485         *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
486         bytes_written = sizeof(uint8_t);
487         msg = msg + bytes_written;
488
489         // req
490         *((frescan_bwres_request_id_t *)msg) = data->req;
491         bytes_written = sizeof(frescan_bwres_request_id_t);
492         msg = msg + bytes_written;
493
494         // return value
495         *((uint8_t *)msg) = data->return_value;
496         bytes_written = sizeof(uint8_t);
497         msg = msg + bytes_written;
498
499         if (data->return_value == FRESCAN_BWRES_REQ_ACCEPTED) {
500                 // new ss values
501                 for(i=0; i<data->contracts_to_neg->size; i++) {
502                         // SS
503                         *((uint16_t *)msg) = data->ss_new->ss[i];
504                         bytes_written = sizeof(uint16_t);
505                         msg = msg + bytes_written;
506
507                         // B - T - P
508                         vres = &frescan_data[data->net].scenario.
509                                                 vres_pool[data->request_node]
510                                                          [data->ss_new->ss[i]];
511
512                         *((frsh_sa_time_t *)msg) = vres->old_c;
513                         bytes_written = sizeof(frsh_sa_time_t);
514                         msg = msg + bytes_written;
515
516                         *((frsh_sa_time_t *)msg) = vres->old_t;
517                         bytes_written = sizeof(frsh_sa_time_t);
518                         msg = msg + bytes_written;
519
520                         *((frsh_sa_prio_t *)msg) = vres->old_p;
521                         bytes_written = sizeof(frsh_sa_prio_t);
522                         msg = msg + bytes_written;
523                 }
524         }
525
526         *size = msg - msg_begin;
527
528         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
529
530         return 0;
531 }
532
533 static int frescan_rep_gn_message_to_request
534                                         (const uint8_t *msg_to_parse,
535                                          frescan_bwres_request_data_t *data,
536                                          size_t size)
537 {
538         int ret;
539         uint8_t *msg;
540         size_t bytes_read;
541         frescan_ss_t ss;
542         frescan_server_params_t server_params;
543
544         msg = (uint8_t *)msg_to_parse;
545
546         // req
547         data->req = *((frescan_bwres_request_id_t *)msg);
548         bytes_read = sizeof(frescan_bwres_request_id_t);
549         msg = msg + bytes_read;
550
551         // return_value
552         data->return_value = *((uint8_t *)msg);
553         bytes_read = sizeof(uint8_t);
554         msg = msg + bytes_read;
555
556         // create the new sporadic servers
557         data->ss_new->size = 0;
558
559         while(msg < msg_to_parse + size) {
560                 // SS
561                 data->ss_new->ss[data->ss_new->size] = *((uint16_t *)msg);
562                 bytes_read = sizeof(uint16_t);
563                 msg = msg + bytes_read;
564
565                 // Budget
566                 server_params.budget =
567                         frsh_rel_time_to_usec
568                         (frsh_sa_time_to_rel_time(*((frsh_sa_time_t *)msg))) /
569                                                 FRESCAN_FRAME_TX_TIME_US;
570                 bytes_read = sizeof(frsh_sa_time_t);
571                 msg = msg + bytes_read;
572
573                 // Period
574                 server_params.period = frsh_sa_time_to_rel_time
575                                                 (*((frsh_sa_time_t *)msg));
576                 bytes_read = sizeof(frsh_sa_time_t);
577                 msg = msg + bytes_read;
578
579                 // Prio
580                 server_params.prio = *((frsh_sa_prio_t *)msg);
581                 bytes_read = sizeof(frsh_sa_prio_t);
582                 msg = msg + bytes_read;
583
584                 // Create server
585                 ret = frescan_servers_create(data->net, &server_params, &ss);
586                 if (ret != 0) return ret;
587
588                 if (ss != data->ss_new->ss[data->ss_new->size]) {
589                         FRESCAN_ERROR("ss from master != ss created\n");
590                         return -1;
591                 }
592
593                 data->ss_new->size++;
594         }
595
596         return 0;
597 }
598
599 /**
600  * frescan_messages_send_request()
601  *
602  * this function converts a request with the necessary data into a message
603  * and sends it.
604  *
605  * @req_data: the request to be sent (NOTE: the network is in req_data)
606  *
607  */
608
609 int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
610 {
611         int ret;
612         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
613         size_t size;
614
615         switch(req_data->type) {
616                 case FRESCAN_BWRES_REQ_GN:
617                         ret = frescan_request_to_gn_message
618                                                         (req_data, msg, &size);
619                         if (ret != 0) return ret;
620                         send_params[req_data->net].to =
621                                                 FRESCAN_BWRES_MASTER_NODE;
622                         break;
623                 case FRESCAN_BWRES_REQ_MC:
624                         ret = frescan_request_to_mc_message
625                                                         (req_data, msg, &size);
626                         if (ret != 0) return ret;
627                         send_params[req_data->net].to = req_data->request_node;
628                         break;
629                 case FRESCAN_BWRES_REP_GN:
630                         ret = frescan_request_to_rep_gn_message
631                                                         (req_data, msg, &size);
632                         if (ret != 0) return ret;
633                         send_params[req_data->net].to = req_data->request_node;
634                         break;
635                 case FRESCAN_BWRES_REQ_RES:
636                 case FRESCAN_BWRES_REQ_RES_GET:
637                 case FRESCAN_BWRES_REP_RES_GET:
638                 case FRESCAN_BWRES_REQ_RES_SET:
639                 case FRESCAN_BWRES_REQ_RES_COMMIT:
640                 case FRESCAN_BWRES_REQ_RES_CANCEL:
641                 default:
642                         FRESCAN_ERROR("request type not supported\n");
643                         return -1;
644         }
645
646         ret = frescan_send(&send_params[req_data->net], msg, size);
647         if (ret != 0) return ret;
648
649         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%u\n",
650               *(frescan_bwres_request_type_t *)msg, size);
651
652         return 0;
653 }
654
655 /**
656  * frescan_messages_recv_request()
657  *
658  * this function BLOCKS the calling thread until receives a message
659  * and transforms it into a request.
660  *
661  * @req_data: the request data to fill from the message bytes (out)
662  *
663  */
664
665 int frescan_messages_recv_request(frescan_network_t    net,
666                                   frescan_bwres_request_id_t *req)
667 {
668         int ret;
669         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
670         uint8_t *msg_to_parse;
671         size_t recv_bytes;
672         frescan_node_t from;
673         frescan_prio_t prio;
674         frescan_bwres_request_data_t *req_data;
675
676         ret = frescan_bwres_requests_alloc(req);
677         if (ret != 0) return ret;
678
679         ret = frescan_bwres_requests_get_data(*req, &req_data);
680         if (ret != 0) return ret;
681
682         ret = frescan_recv(&recv_params[net],
683                             msg,
684                             sizeof(msg),
685                             &recv_bytes,
686                             &from,
687                             &prio);
688         if (ret != 0) return ret;
689
690         DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
691               "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
692               from, recv_bytes, prio, recv_params[net].channel,
693               recv_params[net].flags);
694
695         req_data->request_node = from;
696         req_data->net          = net;
697         req_data->type         = *((uint8_t *)msg);
698
699         msg_to_parse = msg + sizeof(uint8_t);
700         recv_bytes   = recv_bytes - sizeof(uint8_t);
701
702         switch(req_data->type) {
703                 case FRESCAN_BWRES_REQ_GN:
704                         return frescan_gn_message_to_request(msg_to_parse,
705                                                              req_data,
706                                                              recv_bytes);
707                 case FRESCAN_BWRES_REQ_MC:
708                         return frescan_mc_message_to_request(msg_to_parse,
709                                                              req_data,
710                                                              recv_bytes);
711                 case FRESCAN_BWRES_REP_GN:
712                         return frescan_rep_gn_message_to_request(msg_to_parse,
713                                                                  req_data,
714                                                                  recv_bytes);
715                 case FRESCAN_BWRES_REQ_RES:
716                 case FRESCAN_BWRES_REQ_RES_GET:
717                 case FRESCAN_BWRES_REP_RES_GET:
718                 case FRESCAN_BWRES_REQ_RES_SET:
719                 case FRESCAN_BWRES_REQ_RES_COMMIT:
720                 case FRESCAN_BWRES_REQ_RES_CANCEL:
721                 default:
722                         FRESCAN_ERROR("request type %d not supported\n",
723                                       req_data->type);
724                         return -1;
725         }
726 }