]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_bwres_messages.c
add group negotiations to frescan and change all the requests and messages to map...
[frescor/fna.git] / src_frescan / frescan_bwres_messages.c
index 4c899723a6d0a284c623bbd4e53577d70c9a3112..7bef5f0de4275783142796d5e4aa714b4f3a7e14 100644 (file)
 #include "frescan_bwres_messages.h"
 #include "frescan_bwres_requests.h"
 #include "frescan.h"
+#include "frescan_data.h"
 #include "frescan_config.h"
 #include "frescan_debug.h"
+#include "frsh_distributed.h"
 
-#define FRESCAN_BWRES_MX_MSG_SIZE 3000  // TODO: adjust to the minimum
+#define FRESCAN_BWRES_MX_MSG_SIZE 5000  // TODO: adjust to the accurate value
 
 /**
  * frescan_messages_init()
@@ -83,353 +85,440 @@ static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
 
 int frescan_messages_init(frescan_network_t net)
 {
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "initialization\n");
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "initialization\n");
 
         send_params[net].net     = net;
-        send_params[net].channel = FRESCAN_NEG_CHANNEL;
+        send_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
         send_params[net].flags   = FRESCAN_SS | FRESCAN_ASYNC;
-        send_params[net].ss      = the_networks[net].neg_messages_ss_id;
-        send_params[net].to      = FRESCAN_NEG_MASTER_NODE;
+        send_params[net].ss      = frescan_data[net].neg_messages_ss_id;
+        send_params[net].to      = FRESCAN_BWRES_MASTER_NODE;
 
         recv_params[net].net     = net;
-        recv_params[net].channel = FRESCAN_NEG_CHANNEL;
+        recv_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
         recv_params[net].flags   = FRESCAN_SYNC;
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REQ_NEG MESSAGE
- *  =======================
+ *  FRESCAN_BWRES_REQ_GN
+ *  ====================
  *  This message is sent from a SLAVE to the MASTER when the slave wants
- *  to negotiate a new contract. It contains the type (a negotiation 'NEG'
- *  request), the LOCAL request id (so the MASTER can use it in the reply
- *  to identify to which request is replying), a preallocated sporadic
- *  server id (the MASTER will store it in its table together with the
- *  node so we can perform renegotiations and spare capacity distribution
- *  in the future) and the contract.
- *
- *      1     2     2      N
- *  +-----------------------------+
- *  | 'NEG' | REQ | SS | CONTRACT |
- *  +-----------------------------+
- *
+ *  to make a negotiation (including creating new vres, renegotiations and
+ *  cancellations).
  */
 
-struct frescan_req_neg_message_t {
-        frescan_request_type_t   type;
-        frescan_request_id_t     req;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_neg_message(const frescan_request_data_t *data,
-                                          uint8_t *msg)
+static int frescan_request_to_gn_message
+                                (const frescan_bwres_request_data_t *data,
+                                 uint8_t *msg,
+                                 size_t  *size)
 {
-        int ret;
-        struct frescan_req_neg_message_t *neg_msg;
-        size_t req_size, contract_size;
-
-        neg_msg = (struct frescan_req_neg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        neg_msg->type     = FRESCAN_REQ_NEG;
-        neg_msg->req      = data->req;
-        neg_msg->ss       = data->ss;
-
-        ret = frsh_contract_marshal(data->contract,
-                                    msg + req_size,
-                                    FRESCAN_BWRES_MX_MSG_SIZE - req_size,
-                                    &contract_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_marshal return -1\n");
-                return -1;
-        }
-
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n",
-              neg_msg->type, neg_msg->req, neg_msg->ss, contract_size);
+        int ret, i;
+        uint8_t *msg_begin, *msg_tmp;
+        size_t bytes_written;
+
+        msg_begin = msg;
+
+        // type: FRESCAN_GN_MESSAGE
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_GN;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
+
+        // req
+        *((frescan_bwres_request_id_t *)msg) = data->req;
+        bytes_written = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_written;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "GN message req:%u\n", data->req);
+
+        // NEG-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
+
+        *((uint8_t *)msg) = (uint8_t)data->contracts_to_neg->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
+
+        for (i=0; i<data->contracts_to_neg->size; i++) {
+                // reserve 2 bytes for the size of the marshalled contract
+                msg_tmp = msg;
+                msg     = msg + sizeof(uint16_t);
+                // marshal the contract
+                ret = frsh_contract_marshal
+                                (&data->contracts_to_neg->contracts[i],
+                                 msg,
+                                 FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+                                 &bytes_written);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+                        return -1;
+                }
+                // write the size and update the message pointer msg
+                *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+                msg = msg + bytes_written;
 
-        return req_size + contract_size;
-}
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u\n", i, bytes_written);
+        }
 
-static int frescan_neg_message_to_request(const uint8_t *msg,
-                                          frescan_request_data_t *data,
-                                          size_t size)
-{
-        int ret;
-        struct frescan_req_neg_message_t *neg_msg;
-        size_t req_size;
-
-        neg_msg = (struct frescan_req_neg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        data->type        = FRESCAN_REQ_NEG;
-        data->req         = neg_msg->req;
-        data->ss          = neg_msg->ss;
-
-        ret = frsh_contract_unmarshal(data->contract,
-                                      msg  + req_size,  // pointer to contract
-                                      size - req_size); // size marshal '   '
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
-                return -1;
+        // RENEG-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
+
+        *((uint8_t *)msg) = (uint8_t)data->contracts_to_reneg->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
+
+        for (i=0; i<data->contracts_to_reneg->size; i++) {
+                // write the ss
+                *((uint16_t *)msg) = (uint16_t)data->ss_to_reneg->ss[i];
+                bytes_written = sizeof(uint16_t);
+                msg = msg + bytes_written;
+                // reserve 2 bytes for the size of the marshalled contract
+                msg_tmp = msg;
+                msg     = msg + sizeof(uint16_t);
+                // marshal the contract
+                ret = frsh_contract_marshal
+                                (&data->contracts_to_reneg->contracts[i],
+                                 msg,
+                                 FRESCAN_BWRES_MX_MSG_SIZE - (msg - msg_begin),
+                                 &bytes_written);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_marshal return -1\n");
+                        return -1;
+                }
+                // write the size and update the message pointer msg
+                *((uint16_t *)msg_tmp) = (uint16_t)bytes_written;
+                msg = msg + bytes_written;
+
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u ss[%d]:%u\n",
+                      i, bytes_written, i, data->ss_to_reneg->ss[i]);
         }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
-              data->type, data->req, data->ss);
+        // CANCEL-GROUP
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "CANCEL-GROUP num ss:%u\n",
+              data->ss_to_cancel->size);
 
-        return 0;
-}
+        *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-/**
- *
- *  FRESCAN_REQ_RENEG MESSAGE
- *  =========================
- *  This message is sent from a SLAVE to the MASTER when the slave wants
- *  to renegotiate a contract. It contains the type (a renegotiation 'RENEG'
- *  request), the LOCAL request id (so the MASTER can use it in the reply
- *  to identify to which request is replying), the sporadic server id
- *  (the MASTER will look up its table together with the node to find the
- *  appropiate entry) and the contract.
- *
- *      1       2     2      N
- *  +-------------------------------+
- *  | 'RENEG' | REQ | SS | CONTRACT |
- *  +-------------------------------+
- *
- */
+        for (i=0; i<data->ss_to_cancel->size; i++) {
+                // write the ss
+                *((uint16_t *)msg) = (uint16_t)data->ss_to_cancel->ss[i];
+                bytes_written = sizeof(uint16_t);
+                msg = msg + bytes_written;
 
-struct frescan_req_reneg_message_t {
-        frescan_request_type_t   type;
-        frescan_request_id_t     req;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_reneg_message(const frescan_request_data_t *data,
-                                            uint8_t *msg)
-{
-        int ret;
-        size_t req_size, contract_size;
-        struct frescan_req_reneg_message_t *reneg_msg;
-
-        reneg_msg = (struct frescan_req_reneg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_reneg_message_t);
-
-        reneg_msg->type     = FRESCAN_REQ_RENEG;
-        reneg_msg->req      = data->req;
-        reneg_msg->ss       = data->ss;
-
-        ret = frsh_contract_marshal(data->contract,
-                                    msg + req_size,
-                                    FRESCAN_BWRES_MX_MSG_SIZE - req_size,
-                                    &contract_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_marshal return -1\n");
-                return -1;
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "ss[%d]:%u\n", data->ss_to_cancel->ss[i]);
         }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d csize:%u\n",
-              reneg_msg->type, reneg_msg->req, reneg_msg->ss, contract_size);
+        *size = msg - msg_begin;
 
-        return req_size + contract_size;
-}
-
-static int frescan_reneg_message_to_request(const uint8_t *msg,
-                                            frescan_request_data_t *data,
-                                            size_t size)
-{
-        int ret;
-        struct frescan_req_reneg_message_t *reneg_msg;
-        size_t req_size;
-
-        reneg_msg = (struct frescan_req_reneg_message_t *)msg;
-        req_size = sizeof(struct frescan_req_neg_message_t);
-
-        data->type        = FRESCAN_REQ_RENEG;
-        data->req         = reneg_msg->req;
-        data->ss          = reneg_msg->ss;
-
-        ret = frsh_contract_unmarshal(data->contract,
-                                      msg  + req_size,
-                                      size - req_size);
-        if (ret != 0) {
-                FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
-                return -1;
-        }
-
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
-              data->type, data->req, data->ss);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
 
         return 0;
 }
 
-/**
- *  FRESCAN_REQ_CANCEL MESSAGE
- *  ==========================
- *  This message is sent from a SLAVE to the MASTER to cancel a contract.
- *  It contains the type, 'CANCEL' and the sporadic server id (the MASTER will
- *  have to look it up in the table). The MASTER doesnt need to reply this
- *  message.
- *
- *  +---------------+
- *  | 'CANCEL' | SS |
- *  +---------------+
- *
- */
-
-struct frescan_req_cancel_message_t {
-        frescan_request_type_t   type;
-        frescan_ss_t             ss;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_cancel_message(const frescan_request_data_t *data,
-                                             uint8_t *msg)
+static int frescan_gn_message_to_request(const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct frescan_req_cancel_message_t *cancel_msg;
+        int ret, i;
+        uint8_t *msg;
+        size_t bytes_read, contract_size;
+
+        msg = (uint8_t *)msg_to_parse;
+
+        data->contracts_to_neg   = &data->contracts_to_neg_data;
+        data->contracts_to_reneg = &data->contracts_to_reneg_data;
+        data->ss_to_reneg        = &data->ss_to_reneg_data;
+        data->ss_to_cancel       = &data->ss_to_cancel_data;
+        data->ss_new             = &data->ss_new_data;
+
+        // req
+        data->req = *((frescan_bwres_request_id_t *)msg);
+        bytes_read = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "GN message req:%u\n", data->req);
+
+        // NEG-GROUP
+        data->contracts_to_neg->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "NEG-GROUP num contracts:%u\n", data->contracts_to_neg->size);
+
+        for (i=0; i<data->contracts_to_neg->size; i++) {
+                contract_size = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                // unmarshal the contract
+                ret = frsh_contract_unmarshal
+                                (&data->contracts_to_neg->contracts[i],
+                                 msg,
+                                 contract_size);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+                        return -1;
+                }
 
-        cancel_msg = (struct frescan_req_cancel_message_t *)msg;
+                bytes_read = contract_size;
+                msg = msg + bytes_read;
 
-        cancel_msg->type     = FRESCAN_REQ_CANCEL;
-        cancel_msg->ss       = data->ss;
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u\n", i, contract_size);
+        }
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
-              cancel_msg->type, cancel_msg->ss);
+         // RENEG-GROUP
+        data->contracts_to_reneg->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "RENEG-GROUP num contracts:%u\n",data->contracts_to_reneg->size);
+
+        for (i=0; i<data->contracts_to_reneg->size; i++) {
+                data->ss_to_reneg->ss[i] = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                contract_size = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                // unmarshal the contract
+                ret = frsh_contract_unmarshal
+                                (&data->contracts_to_reneg->contracts[i],
+                                 msg,
+                                 contract_size);
+                if (ret != 0) {
+                        FRESCAN_ERROR("frsh_contract_unmarshal return -1\n");
+                        return -1;
+                }
 
-        return sizeof(struct frescan_req_cancel_message_t);
-}
+                bytes_read = contract_size;
+                msg = msg + bytes_read;
 
-static int frescan_cancel_message_to_request(const uint8_t *msg,
-                                             frescan_request_data_t *data)
-{
-        struct frescan_req_cancel_message_t *cancel_msg;
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "contract[%d].size:%u ss[%d]:%u\n",
+                      i, contract_size, i, data->ss_to_reneg->ss[i]);
+        }
 
-        cancel_msg = (struct frescan_req_cancel_message_t *)msg;
+        // CANCEL-GROUP
+        data->ss_to_cancel->size = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
 
-        data->type        = FRESCAN_REQ_CANCEL;
-        data->ss          = cancel_msg->ss;
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+              "CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
-              data->type, data->ss);
+        for (i=0; i<data->ss_to_cancel->size; i++) {
+                // write the ss
+                data->ss_to_cancel->ss[i] = *((uint16_t *)msg);
+                bytes_read = sizeof(uint16_t);
+                msg = msg + bytes_read;
+
+                DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+                      "ss[%d]:%u\n", data->ss_to_cancel->ss[i]);
+        }
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REP_CHANGE MESSAGE
- *  ==========================
- *  This message is sent from the MASTER to a slave as a reply to a
- *  FRESCAN_REQ_NEG or a FRESCAN_REQ_RENEG, to say if they were admited.
- *  It contains the type 'REPNEG', the request ID of the slave, a
- *  return value to say if the contract is admited or not, and the final
- *  values if it was admited
- *
- *  +----------------------------------------------+
- *  | 'REPNEG' | REQ | RETURN_VALUE | FINAL_VALUES |
- *  +----------------------------------------------+
- *
+ *  FRESCAN_BWRES_REQ_MC
+ *  ====================
+ *  This message is sent from the MASTER to a slave when there is a change
+ *  in the budget value assigned by the spare capacity algorithm.
  */
 
-struct frescan_rep_neg_message_t {
-        frescan_request_type_t    type;
-        frescan_request_id_t      req;
-        frescan_request_retval_t  return_value;
-        frescan_server_params_t   final_values;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
-                                             uint8_t *msg)
+static int frescan_request_to_mc_message
+                                (const frescan_bwres_request_data_t *data,
+                                 uint8_t *msg,
+                                 size_t  *size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
-
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+        frescan_bwres_vres_t *vres;
+        uint8_t *msg_begin;
+        size_t bytes_written;
+
+        msg_begin = msg;
+
+        // type: FRESCAN_GN_MESSAGE
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REQ_MC;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
+
+        // write the SS-mode_change_type-values fields
+        list_for_each_entry(vres,
+                            &frescan_data[data->net].mode_change_list
+                                                        [data->request_node],
+                            mode_change_list)
+        {
+                if ((vres->mode_change_type & data->mode_change_type) !=
+                     data->mode_change_type) continue;
+
+                *((frescan_ss_t *)msg) = vres->ss;
+                bytes_written = sizeof(frescan_ss_t);
+                msg = msg + bytes_written;
+
+                *((uint8_t *)msg) = (uint8_t)data->mode_change_type;
+                bytes_written = sizeof(uint8_t);
+                msg = msg + bytes_written;
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+                                              FRESCAN_BWRES_MC_BUDGET_DEC)) {
+                        *((frsh_sa_time_t *)msg) = vres->old_c;
+                        bytes_written = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_written;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+                                              FRESCAN_BWRES_MC_PERIOD_DEC)) {
+                        *((frsh_sa_time_t *)msg) = vres->old_t;
+                        bytes_written = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_written;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+                                              FRESCAN_BWRES_MC_PRIO_DEC)) {
+                        *((frsh_sa_prio_t *)msg) = vres->old_p;
+                        bytes_written = sizeof(frsh_sa_prio_t);
+                        msg = msg + bytes_written;
+                }
+        }
 
-        repneg_msg->type         = FRESCAN_REP_NEG;
-        repneg_msg->req          = data->req;
-        repneg_msg->return_value = data->return_value;
-        repneg_msg->final_values = data->final_values;
+        *size = msg - msg_begin;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              repneg_msg->type, repneg_msg->req, repneg_msg->return_value);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
 
-        return sizeof(struct frescan_rep_neg_message_t);
+        return 0;
 }
 
-static int frescan_repneg_message_to_request(const uint8_t *msg,
-                                             frescan_request_data_t *data)
+static int frescan_mc_message_to_request(const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
-
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
-
-        data->type         = FRESCAN_REP_NEG;
-        data->req          = repneg_msg->req;
-        data->return_value = repneg_msg->return_value;
-        data->final_values = repneg_msg->final_values;
-
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              data->type, data->req, data->return_value);
+        uint8_t *msg;
+        size_t bytes_read;
+        frescan_ss_t ss;
+        frescan_bwres_vres_t *vres;
+        frescan_node_t me;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "MC message\n");
+
+        msg = (uint8_t *)msg_to_parse;
+        me = frescan_data[data->net].local_node;
+        data->mode_change_type = 0;
+
+        while(msg < msg_to_parse + size) {
+                ss = *((frescan_ss_t *)msg);
+                bytes_read = sizeof(frescan_ss_t);
+                msg = msg + bytes_read;
+
+                vres = &frescan_data[data->net].scenario.vres_pool[me][ss];
+
+                vres->mode_change_type = *((uint8_t *)msg);
+                bytes_read = sizeof(uint8_t);
+                msg = msg + bytes_read;
+
+                if (vres->mode_change_type & (FRESCAN_BWRES_MC_BUDGET_INC |
+                                              FRESCAN_BWRES_MC_BUDGET_DEC)) {
+                        vres->old_c = *((frsh_sa_time_t *)msg);
+                        bytes_read = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PERIOD_INC |
+                                              FRESCAN_BWRES_MC_PERIOD_DEC)) {
+                        vres->old_t = *((frsh_sa_time_t *)msg);
+                        bytes_read = sizeof(frsh_sa_time_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (data->mode_change_type & (FRESCAN_BWRES_MC_PRIO_INC |
+                                              FRESCAN_BWRES_MC_PRIO_DEC)) {
+                        vres->old_p = *((frsh_sa_prio_t *)msg);
+                        bytes_read = sizeof(frsh_sa_prio_t);
+                        msg = msg + bytes_read;
+                }
+
+                if (vres->mode_change_type != 0) {
+                        list_add_tail(&(vres->mode_change_list),
+                                      &(frescan_data[data->net].
+                                                      mode_change_list[me]));
+                }
+
+                data->mode_change_type |= vres->mode_change_type;
+        }
 
         return 0;
 }
 
 /**
- *
- *  FRESCAN_REP_NEG MESSAGE
- *  =======================
+ *  FRESCAN_BWRES_REP_GN
+ *  ====================
  *  This message is sent from the MASTER to a slave as a reply to a
- *  FRESCAN_REQ_NEG or a FRESCAN_REQ_RENEG, to say if they were admited.
- *  It contains the type 'REPNEG', the request ID of the slave, a
- *  return value to say if the contract is admited or not, and the final
- *  values if it was admited
- *
- *  +----------------------------------------------+
- *  | 'REPNEG' | REQ | RETURN_VALUE | FINAL_VALUES |
- *  +----------------------------------------------+
- *
+ *  FRESCAN_BWRES_REQ_GN message
  */
 
-struct frescan_rep_neg_message_t {
-        frescan_request_type_t    type;
-        frescan_request_id_t      req;
-        frescan_request_retval_t  return_value;
-        frescan_server_params_t   final_values;
-}  __attribute__ ((packed));
-
-static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
-                                             uint8_t *msg)
+static int frescan_request_to_rep_gn_message
+                        (const frescan_bwres_request_data_t *data,
+                         uint8_t *msg,
+                         size_t  *size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
+        uint8_t *msg_begin;
+        size_t bytes_written;
+
+        msg_begin = msg;
 
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+        // type
+        *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-        repneg_msg->type         = FRESCAN_REP_NEG;
-        repneg_msg->req          = data->req;
-        repneg_msg->return_value = data->return_value;
-        // TODO: use final values only if it was accepted!
-        repneg_msg->final_values = data->final_values;
+        // req
+        *((frescan_bwres_request_id_t *)msg) = data->req;
+        bytes_written = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_written;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              repneg_msg->type, repneg_msg->req, repneg_msg->return_value);
+        // return value
+        *((uint8_t *)msg) = data->return_value;
+        bytes_written = sizeof(uint8_t);
+        msg = msg + bytes_written;
 
-        return sizeof(struct frescan_rep_neg_message_t);
+        *size = msg - msg_begin;
+
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
+
+        return 0;
 }
 
-static int frescan_repneg_message_to_request(const uint8_t *msg,
-                                             frescan_request_data_t *data)
+static int frescan_rep_gn_message_to_request
+                                        (const uint8_t *msg_to_parse,
+                                         frescan_bwres_request_data_t *data,
+                                         size_t size)
 {
-        struct frescan_rep_neg_message_t *repneg_msg;
+        uint8_t *msg;
+        size_t bytes_read;
 
-        repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+        msg = (uint8_t *)msg_to_parse;
 
-        data->type         = FRESCAN_REP_NEG;
-        data->req          = repneg_msg->req;
-        data->return_value = repneg_msg->return_value;
-        // TODO: use final values only if it was accepted!
-        data->final_values = repneg_msg->final_values;
+        // req
+        data->req = *((frescan_bwres_request_id_t *)msg);
+        bytes_read = sizeof(frescan_bwres_request_id_t);
+        msg = msg + bytes_read;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
-              data->type, data->req, data->return_value);
+        // return_value
+        data->return_value = *((uint8_t *)msg);
+        bytes_read = sizeof(uint8_t);
+        msg = msg + bytes_read;
 
         return 0;
 }
@@ -444,33 +533,38 @@ static int frescan_repneg_message_to_request(const uint8_t *msg,
  *
  */
 
-int frescan_messages_send_request(const frescan_request_data_t *req_data)
+int frescan_messages_send_request(const frescan_bwres_request_data_t *req_data)
 {
         int ret;
         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
         size_t size;
 
         switch(req_data->type) {
-                case FRESCAN_REQ_NEG:
-                        size = frescan_request_to_neg_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
-                        break;
-                case FRESCAN_REQ_RENEG:
-                        size = frescan_request_to_reneg_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
+                case FRESCAN_BWRES_REQ_GN:
+                        ret = frescan_request_to_gn_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
+                        send_params[req_data->net].to =
+                                                FRESCAN_BWRES_MASTER_NODE;
                         break;
-                case FRESCAN_REQ_CANCEL:
-                        size = frescan_request_to_cancel_message(req_data, msg);
-                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
-                        break;
-                case FRESCAN_REP_CHANGE:
-                        size = frescan_request_to_repchange_message(req_data, msg);
+                case FRESCAN_BWRES_REQ_MC:
+                        ret = frescan_request_to_mc_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
                         send_params[req_data->net].to = req_data->request_node;
                         break;
-                case FRESCAN_REP_NEG:
-                        size = frescan_request_to_repneg_message(req_data, msg);
+                case FRESCAN_BWRES_REP_GN:
+                        ret = frescan_request_to_rep_gn_message
+                                                        (req_data, msg, &size);
+                        if (ret != 0) return ret;
                         send_params[req_data->net].to = req_data->request_node;
                         break;
+                case FRESCAN_BWRES_REQ_RES:
+                case FRESCAN_BWRES_REQ_RES_GET:
+                case FRESCAN_BWRES_REP_RES_GET:
+                case FRESCAN_BWRES_REQ_RES_SET:
+                case FRESCAN_BWRES_REQ_RES_COMMIT:
+                case FRESCAN_BWRES_REQ_RES_CANCEL:
                 default:
                         FRESCAN_ERROR("request type not supported\n");
                         return -1;
@@ -479,8 +573,8 @@ int frescan_messages_send_request(const frescan_request_data_t *req_data)
         ret = frescan_send(&send_params[req_data->net], msg, size);
         if (ret != 0) return ret;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%d\n",
-              *(frescan_request_type_t *)msg, size);
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%u\n",
+              *(frescan_bwres_request_type_t *)msg, size);
 
         return 0;
 }
@@ -496,19 +590,20 @@ int frescan_messages_send_request(const frescan_request_data_t *req_data)
  */
 
 int frescan_messages_recv_request(frescan_network_t    net,
-                                  frescan_request_id_t *req)
+                                  frescan_bwres_request_id_t *req)
 {
         int ret;
         uint8_t msg[FRESCAN_BWRES_MX_MSG_SIZE];
+        uint8_t *msg_to_parse;
         size_t recv_bytes;
         frescan_node_t from;
         frescan_prio_t prio;
-        frescan_request_data_t *req_data;
+        frescan_bwres_request_data_t *req_data;
 
-        ret = frescan_requests_alloc(req);
+        ret = frescan_bwres_requests_alloc(req);
         if (ret != 0) return ret;
 
-        ret = frescan_requests_get_data(*req, &req_data);
+        ret = frescan_bwres_requests_get_data(*req, &req_data);
         if (ret != 0) return ret;
 
         ret = frescan_recv(&recv_params[net],
@@ -519,32 +614,40 @@ int frescan_messages_recv_request(frescan_network_t    net,
                             &prio);
         if (ret != 0) return ret;
 
-        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG,
+        DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
               "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
               from, recv_bytes, prio, recv_params[net].channel,
               recv_params[net].flags);
 
         req_data->request_node = from;
-        req_data->net = net;
-
-        switch(*((frescan_request_type_t *)msg)) {
-                case FRESCAN_REQ_NEG:
-                        return frescan_neg_message_to_request(msg,
-                                                              req_data,
-                                                              recv_bytes);
-                case FRESCAN_REQ_RENEG:
-                        return frescan_reneg_message_to_request(msg,
-                                                                req_data,
-                                                                recv_bytes);
-                case FRESCAN_REQ_CANCEL:
-                        return frescan_cancel_message_to_request(msg, req_data);
-                case FRESCAN_REP_CHANGE:
-                        return frescan_repchange_message_to_request(msg, req_data);
-                case FRESCAN_REP_NEG:
-                        return frescan_repneg_message_to_request(msg, req_data);
+        req_data->net          = net;
+        req_data->type         = *((uint8_t *)msg);
+
+        msg_to_parse = msg + sizeof(uint8_t);
+        recv_bytes   = recv_bytes - sizeof(uint8_t);
+
+        switch(req_data->type) {
+                case FRESCAN_BWRES_REQ_GN:
+                        return frescan_gn_message_to_request(msg_to_parse,
+                                                             req_data,
+                                                             recv_bytes);
+                case FRESCAN_BWRES_REQ_MC:
+                        return frescan_mc_message_to_request(msg_to_parse,
+                                                             req_data,
+                                                             recv_bytes);
+                case FRESCAN_BWRES_REP_GN:
+                        return frescan_rep_gn_message_to_request(msg_to_parse,
+                                                                 req_data,
+                                                                 recv_bytes);
+                case FRESCAN_BWRES_REQ_RES:
+                case FRESCAN_BWRES_REQ_RES_GET:
+                case FRESCAN_BWRES_REP_RES_GET:
+                case FRESCAN_BWRES_REQ_RES_SET:
+                case FRESCAN_BWRES_REQ_RES_COMMIT:
+                case FRESCAN_BWRES_REQ_RES_CANCEL:
                 default:
-                        FRESCAN_ERROR("request type %X not supported\n",
-                              *(frescan_request_type_t *)msg);
+                        FRESCAN_ERROR("request type %d not supported\n",
+                                      req_data->type);
                         return -1;
         }
 }