*
* @author Daniel Sangorrin <daniel.sangorrin@unican.es>
*
+ * @license
+ *
+ * -----------------------------------------------------------------------
+ * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
+ *
+ * Universidad de Cantabria, SPAIN
+ * University of York, UK
+ * Scuola Superiore Sant'Anna, ITALY
+ * Kaiserslautern University, GERMANY
+ * Univ. Politécnica Valencia, SPAIN
+ * Czech Technical University in Prague, CZECH REPUBLIC
+ * ENEA SWEDEN
+ * Thales Communication S.A. FRANCE
+ * Visual Tools S.A. SPAIN
+ * Rapita Systems Ltd UK
+ * Evidence ITALY
+ *
+ * See http://www.frescor.org for a link to partners' websites
+ *
+ * FRESCOR project (FP6/2005/IST/5-034026) is funded
+ * in part by the European Union Sixth Framework Programme
+ * The European Union is not liable of any use that may be
+ * made of this code.
+ *
+ * This file is part of FRESCAN
+ *
+ * FRESCAN is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * FRESCAN is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * distributed with FRESCAN; see file COPYING. If not, write to the
+ * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * As a special exception, including FRESCAN header files in a file,
+ * instantiating FRESCAN generics or templates, or linking other files
+ * with FRESCAN objects to produce an executable application, does not
+ * by itself cause the resulting executable application to be covered
+ * by the GNU General Public License. This exception does not
+ * however invalidate any other reasons why the executable file might be
+ * covered by the GNU Public License.
+ * -----------------------------------------------------------------------
+ *
*/
#include <string.h>
#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 5000 // TODO: adjust to the accurate value
/**
- *
- * FRESCAN_REQ_NEG MESSAGE
- * =======================
- * 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 |
- * +-----------------------------+
- *
+ * frescan_messages_init()
*/
-struct frescan_req_neg_message_t {
- frescan_request_type_t type;
- frescan_request_id_t req;
- frescan_ss_t ss;
- frescan_contract_t contract;
-} __attribute__ ((packed));
+static frescan_send_params_t send_params[FRESCAN_MX_NETWORKS];
+static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
-static int frescan_request_to_neg_message(const frescan_request_data_t *data,
- uint8_t *msg)
+int frescan_messages_init(frescan_network_t net)
{
- struct frescan_req_neg_message_t *neg_msg;
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "initialization\n");
- neg_msg = (struct frescan_req_neg_message_t *)msg;
+ send_params[net].net = net;
+ send_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
+ send_params[net].flags = FRESCAN_SS | FRESCAN_ASYNC;
+ send_params[net].ss = frescan_data[net].neg_messages_ss_id;
+ send_params[net].to = FRESCAN_BWRES_MASTER_NODE;
- neg_msg->type = FRESCAN_REQ_NEG;
- neg_msg->req = data->req;
- neg_msg->ss = data->ss;
- neg_msg->contract = *(data->contract);
+ recv_params[net].net = net;
+ recv_params[net].channel = FRESCAN_BWRES_NEG_CHANNEL;
+ recv_params[net].flags = FRESCAN_SYNC;
return 0;
}
-static int frescan_neg_message_to_request(const uint8_t *msg,
- frescan_request_data_t *data)
+/**
+ * FRESCAN_BWRES_REQ_GN
+ * ====================
+ * This message is sent from a SLAVE to the MASTER when the slave wants
+ * to make a negotiation (including creating new vres, renegotiations and
+ * cancellations).
+ */
+
+static int frescan_request_to_gn_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
{
- struct frescan_req_neg_message_t *neg_msg;
+ 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;
- neg_msg = (struct frescan_req_neg_message_t *)msg;
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u\n", i, bytes_written);
+ }
- data->type = FRESCAN_REQ_NEG;
- data->req = neg_msg->req;
- data->ss = neg_msg->ss;
- *(data->contract) = neg_msg->contract;
+ // 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]);
+ }
- return 0;
-}
+ // CANCEL-GROUP
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "CANCEL-GROUP num ss:%u\n",
+ data->ss_to_cancel->size);
-/**
- *
- * 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 |
- * +-------------------------------+
- *
- */
+ *((uint8_t *)msg) = (uint8_t)data->ss_to_cancel->size;
+ bytes_written = sizeof(uint8_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;
- frescan_contract_t contract;
-} __attribute__ ((packed));
+ 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;
-static int frescan_request_to_reneg_message(const frescan_request_data_t *data,
- uint8_t *msg)
-{
- struct frescan_req_reneg_message_t *reneg_msg;
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "ss[%d]:%u\n", data->ss_to_cancel->ss[i]);
+ }
- reneg_msg = (struct frescan_req_reneg_message_t *)msg;
+ *size = msg - msg_begin;
- reneg_msg->type = FRESCAN_REQ_RENEG;
- reneg_msg->req = data->req;
- reneg_msg->ss = data->ss;
- reneg_msg->contract = *(data->contract);
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
return 0;
}
-static int frescan_reneg_message_to_request(const uint8_t *msg,
- frescan_request_data_t *data)
+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_reneg_message_t *reneg_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;
+ }
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u\n", i, contract_size);
+ }
+
+ // 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;
+ }
+
+ bytes_read = contract_size;
+ msg = msg + bytes_read;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "contract[%d].size:%u ss[%d]:%u\n",
+ i, contract_size, i, data->ss_to_reneg->ss[i]);
+ }
- reneg_msg = (struct frescan_req_reneg_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_RENEG;
- data->req = reneg_msg->req;
- data->ss = reneg_msg->ss;
- *(data->contract) = reneg_msg->contract;
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG,
+ "CANCEL-GROUP num ss:%u\n", data->ss_to_cancel->size);
+
+ 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_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 |
- * +---------------+
- *
+ * 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_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_request_to_mc_message
+ (const frescan_bwres_request_data_t *data,
+ uint8_t *msg,
+ size_t *size)
{
- struct frescan_req_cancel_message_t *cancel_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;
+ }
+ }
- cancel_msg = (struct frescan_req_cancel_message_t *)msg;
+ *size = msg - msg_begin;
- cancel_msg->type = FRESCAN_REQ_CANCEL;
- cancel_msg->ss = data->ss;
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "size:%u\n", *size);
return 0;
}
-static int frescan_cancel_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_req_cancel_message_t *cancel_msg;
-
- cancel_msg = (struct frescan_req_cancel_message_t *)msg;
-
- data->type = FRESCAN_REQ_CANCEL;
- data->ss = cancel_msg->ss;
+ 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 and a
- * return value to say if the contract is admited, not admited or if
- * there was an error.
- *
- * +-------------------------------+
- * | 'REPNEG' | REQ | RETURN_VALUE |
- * +-------------------------------+
- *
+ * 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;
-} __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;
+
+ // type
+ *((uint8_t *)msg) = (uint8_t)FRESCAN_BWRES_REP_GN;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
- repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+ // req
+ *((frescan_bwres_request_id_t *)msg) = data->req;
+ bytes_written = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_written;
- repneg_msg->type = FRESCAN_REP_NEG;
- repneg_msg->req = data->req;
- repneg_msg->return_value = data->return_value;
+ // return value
+ *((uint8_t *)msg) = data->return_value;
+ bytes_written = sizeof(uint8_t);
+ msg = msg + bytes_written;
+
+ *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;
+
+ msg = (uint8_t *)msg_to_parse;
- repneg_msg = (struct frescan_rep_neg_message_t *)msg;
+ // req
+ data->req = *((frescan_bwres_request_id_t *)msg);
+ bytes_read = sizeof(frescan_bwres_request_id_t);
+ msg = msg + bytes_read;
- data->type = FRESCAN_REP_NEG;
- data->req = repneg_msg->req;
- data->return_value = repneg_msg->return_value;
+ // return_value
+ data->return_value = *((uint8_t *)msg);
+ bytes_read = sizeof(uint8_t);
+ msg = msg + bytes_read;
return 0;
}
/**
- * frescan_request_to_message() - converts a request into a network message
+ * frescan_messages_send_request()
*
* this function converts a request with the necessary data into a message
- * that can be sent through the network.
+ * and sends it.
*
- * @req_data: the request data to fill the message bytes (in)
- * @msg: buffer with the bytes that will be sent to the network (out)
+ * @req_data: the request to be sent (NOTE: the network is in req_data)
*
*/
-int frescan_request_to_message(const frescan_request_data_t *req_data,
- uint8_t *msg)
+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:
- return frescan_request_to_neg_message(req_data, msg);
- case FRESCAN_REQ_RENEG:
- return frescan_request_to_reneg_message(req_data, msg);
- case FRESCAN_REQ_CANCEL:
- return frescan_request_to_cancel_message(req_data, msg);
- case FRESCAN_REP_NEG:
- return frescan_request_to_repneg_message(req_data, msg);
+ 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_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_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:
- ERROR("request type not supported\n");
+ FRESCAN_ERROR("request type not supported\n");
return -1;
}
+
+ ret = frescan_send(&send_params[req_data->net], msg, size);
+ if (ret != 0) return ret;
+
+ DEBUG(FRESCAN_BWRES_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%u\n",
+ *(frescan_bwres_request_type_t *)msg, size);
+
+ return 0;
}
/**
- * frescan_message_to_request() - converts a network message into a request
+ * frescan_messages_recv_request()
*
- * this function is the opposite to the previous one. It will be used by
- * the acceptor threads to transform messages received from the network
- * into requests.
+ * this function BLOCKS the calling thread until receives a message
+ * and transforms it into a request.
*
- * @msg: buffer with the bytes received from the network (in)
* @req_data: the request data to fill from the message bytes (out)
*
*/
-int frescan_message_to_request(const uint8_t *msg,
- frescan_request_data_t *req_data)
-{
- switch(*((frescan_request_type_t *)msg)) {
- case FRESCAN_REQ_NEG:
- return frescan_neg_message_to_request(msg, req_data);
- case FRESCAN_REQ_RENEG:
- return frescan_reneg_message_to_request(msg, req_data);
- case FRESCAN_REQ_CANCEL:
- return frescan_cancel_message_to_request(msg, req_data);
- case FRESCAN_REP_NEG:
- return frescan_repneg_message_to_request(msg, req_data);
- default:
- ERROR("request type not supported\n");
- return -1;
- }
-}
-
-/*
-
-int frescan_message_parse(frescan_network_t net,
- const uint8_t *msg,
- size_t size,
- frescan_node_t from)
+int frescan_messages_recv_request(frescan_network_t net,
+ frescan_bwres_request_id_t *req)
{
int ret;
- frescan_msg_type_t type;
- size_t num;
- uint8_t *tmp;
- frescan_contract_t contract;
- frescan_request_id_t request_id;
- frescan_robj_id_t reply;
- uint8_t reply_msg[200];
- int accepted;
- frescan_neg_return_info_t *neg_return_info;
- int bytes_to_send;
- frescan_send_params_t params;
- frescan_server_params_t server_params;
-
- params.net = net;
- params.channel = FRESCAN_NEG_CHANNEL;
- params.flags = FRESCAN_SS | FRESCAN_ASYNC;
- params.ss = the_networks[net].neg_messages_ss_id;
- params.to = from;
-
- tmp = (uint8_t *)msg;
- type = (frescan_msg_type_t)*msg;
- tmp++;
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "parsing message, type:%u, size:%u\n", type, size);
-
- switch (type) {
- case FRESCAN_MSG_TYPE_NEG:
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "FRESCAN_MSG_TYPE_NEG\n");
-
- num = 2;
- memcpy(&request_id, tmp, num);
- tmp = tmp + num;
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "request id: %d (2 bytes)\n", request_id);
-
- num = sizeof(frescan_contract_t);
- memcpy(&contract, tmp, num);
- tmp = tmp + num;
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "contract (%d bytes)\n", num);
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "min_budget:%u max_period:(%u,%u)\n",
- contract.min_values.budget,
- contract.min_values.period.tv_sec,
- contract.min_values.period.tv_nsec);
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "max_budget:%u min_period:(%u,%u)\n",
- contract.max_values.budget,
- contract.max_values.period.tv_sec,
- contract.max_values.period.tv_nsec);
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "prio:%u\n", contract.prio);
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "TODO: sched test and add contract to table\n");
-// accepted = 1;
-// server_params.values.budget = contract.min_values.budget;
-// server_params.values.period = contract.min_values.period;
-// server_params.prio = contract.prio;
- FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
- accepted = 1;
- FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
-
- server_params.values.budget = 69;
- server_params.values.period.tv_sec = 33;
- server_params.values.period.tv_nsec = 666;
- server_params.prio = 2;
-
- DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
- "accepted:%u send results, net:%u to:%u ss:%u\n",
- accepted, params.net, params.to, params.ss);
-
- bytes_to_send = frescan_repneg_message_create
- (reply_msg,
- request_id,
- accepted,
- &server_params);
-
- DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
- "bytes_to_send:%u\n", bytes_to_send);
-
- if (bytes_to_send <= 0) {
- ERROR("creating reply_msg to neg\n");
- return -1;
- }
-
- ret = frescan_send(¶ms, reply_msg, bytes_to_send);
- if (ret != 0) {
- ERROR("error while sending neg request to master\n");
- return ret;
- }
- break;
-
- case FRESCAN_MSG_TYPE_REP_NEG:
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "FRESCAN_MSG_TYPE_REP_NEG\n");
-
- num = 2;
- memcpy(&request_id, tmp, num);
- tmp = tmp + num;
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "request id: %d (2 bytes)\n", request_id);
-
- ret = frescan_request_get_return_info
- (request_id,
- (void *)&neg_return_info);
- if (ret != 0) {
- ERROR("error getting final_values_ref\n");
- return ret;
- }
-
- accepted = (int)*tmp;
- tmp++;
-
- if (accepted) {
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "contract accepted:%d\n", accepted);
- neg_return_info->error = 0;
-
- num = sizeof(frescan_budget_period_t);
- memcpy(&server_params.values, tmp, num);
- tmp = tmp + num;
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "final budget:%u period:(%u,%u)\n",
- server_params.values.budget,
- server_params.values.period.tv_sec,
- server_params.values.period.tv_nsec);
-
- num = 1;
- memcpy(&server_params.prio, tmp, num);
- tmp = tmp + num;
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "server prio:%u\n", server_params.prio);
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "create sporadic server with results\n");
-
- ret = frescan_servers_create(net,
- &server_params,
- &neg_return_info->id);
- if (ret != 0) {
- ERROR("error creating server\n");
- return ret;
- }
- } else {
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "contract not accepted:%d\n", accepted);
- neg_return_info->error = -1;
- }
-
- DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
- "signal the request id with the results\n");
-
- ret = frescan_request_get_reply(request_id, &reply);
- if (ret != 0) {
- ERROR("error getting reply object\n");
- return ret;
- }
-
- ret = frescan_replyobject_signal(reply);
- if (ret != 0) {
- ERROR("error while sending neg request to master\n");
- return ret;
- }
- break;
+ 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_bwres_request_data_t *req_data;
+
+ ret = frescan_bwres_requests_alloc(req);
+ if (ret != 0) return ret;
+
+ ret = frescan_bwres_requests_get_data(*req, &req_data);
+ if (ret != 0) return ret;
+
+ ret = frescan_recv(&recv_params[net],
+ msg,
+ sizeof(msg),
+ &recv_bytes,
+ &from,
+ &prio);
+ if (ret != 0) return ret;
+
+ 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;
+ 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:
- ERROR("type not known %u\n", type);
+ FRESCAN_ERROR("request type %d not supported\n",
+ req_data->type);
return -1;
}
-
- return 0;
-}*/
+}