]> rtime.felk.cvut.cz Git - frescor/fna.git/blobdiff - src_frescan/frescan_bwres_messages.c
added the functions to renegotiate and cancel a contract. TODO: there is a bug when...
[frescor/fna.git] / src_frescan / frescan_bwres_messages.c
index 2d1cd8d4145102696a1268508cb752b1054a8043..870af2b56f8c0d2a9a3d345b00b23aadf0d9ca2e 100644 (file)
 #include "frescan_config.h"
 #include "frescan_debug.h"
 
+/**
+ * frescan_messages_init()
+ */
+
+static frescan_send_params_t send_params[FRESCAN_MX_NETWORKS];
+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");
+
+        send_params[net].net     = net;
+        send_params[net].channel = FRESCAN_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;
+
+        recv_params[net].net     = net;
+        recv_params[net].channel = FRESCAN_NEG_CHANNEL;
+        recv_params[net].flags   = FRESCAN_SYNC;
+
+        return 0;
+}
+
 /**
  *
  *  FRESCAN_REQ_NEG MESSAGE
@@ -60,7 +84,7 @@ static int frescan_request_to_neg_message(const frescan_request_data_t *data,
         neg_msg->ss       = data->ss;
         neg_msg->contract = *(data->contract);
 
-        return 0;
+        return sizeof(struct frescan_req_neg_message_t);
 }
 
 static int frescan_neg_message_to_request(const uint8_t *msg,
@@ -115,7 +139,7 @@ static int frescan_request_to_reneg_message(const frescan_request_data_t *data,
         reneg_msg->ss       = data->ss;
         reneg_msg->contract = *(data->contract);
 
-        return 0;
+        return sizeof(struct frescan_req_reneg_message_t);
 }
 
 static int frescan_reneg_message_to_request(const uint8_t *msg,
@@ -162,7 +186,7 @@ static int frescan_request_to_cancel_message(const frescan_request_data_t *data,
         cancel_msg->type     = FRESCAN_REQ_CANCEL;
         cancel_msg->ss       = data->ss;
 
-        return 0;
+        return sizeof(struct frescan_req_cancel_message_t);
 }
 
 static int frescan_cancel_message_to_request(const uint8_t *msg,
@@ -184,20 +208,21 @@ static int frescan_cancel_message_to_request(const uint8_t *msg,
  *  =======================
  *  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.
+ *  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 |
- *  +-------------------------------+
+ *  +----------------------------------------------+
+ *  | 'REPNEG' | REQ | RETURN_VALUE | FINAL_VALUES |
+ *  +----------------------------------------------+
  *
  */
 
 struct frescan_rep_neg_message_t {
-        frescan_request_type_t   type;
-        frescan_request_id_t     req;
-        frescan_request_retval_t return_value;
+        frescan_request_type_t    type;
+        frescan_request_id_t      req;
+        frescan_request_retval_t  return_value;
+        frescan_sa_final_values_t final_values;
 }  __attribute__ ((packed));
 
 static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
@@ -210,8 +235,9 @@ static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
         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;
 
-        return 0;
+        return sizeof(struct frescan_rep_neg_message_t);
 }
 
 static int frescan_repneg_message_to_request(const uint8_t *msg,
@@ -224,54 +250,103 @@ static int frescan_repneg_message_to_request(const uint8_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;
 
         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_request_data_t *req_data)
 {
+        int ret;
+        uint8_t msg[2000]; // TODO: use a constant for max neg message size
+        size_t size;
+
         switch(req_data->type) {
                 case FRESCAN_REQ_NEG:
-                        return frescan_request_to_neg_message(req_data, msg);
+                        size = frescan_request_to_neg_message(req_data, msg);
+                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
+                        break;
                 case FRESCAN_REQ_RENEG:
-                        return frescan_request_to_reneg_message(req_data, msg);
+                        size = frescan_request_to_reneg_message(req_data, msg);
+                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
+                        break;
                 case FRESCAN_REQ_CANCEL:
-                        return frescan_request_to_cancel_message(req_data, msg);
+                        size = frescan_request_to_cancel_message(req_data, msg);
+                        send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
+                        break;
                 case FRESCAN_REP_NEG:
-                        return frescan_request_to_repneg_message(req_data, msg);
+                        size = frescan_request_to_repneg_message(req_data, msg);
+                        send_params[req_data->net].to = req_data->request_node;
+                        break;
                 default:
                         ERROR("request type not supported\n");
                         return -1;
         }
+
+        DEBUG(true, "request type %X sent, size %d\n",
+              *(frescan_request_type_t *)msg, size);
+
+        ret = frescan_send(&send_params[req_data->net], msg, size);
+        if (ret != 0) return ret;
+
+        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)
+int frescan_messages_recv_request(frescan_network_t    net,
+                                  frescan_request_id_t *req)
 {
+        int ret;
+        uint8_t msg[2000]; // TODO: use a constant with the max neg message size
+        size_t recv_bytes;
+        frescan_node_t from;
+        frescan_prio_t prio;
+        frescan_request_data_t *req_data;
+
+        ret = frescan_requests_alloc(req);
+        if (ret != 0) return ret;
+
+        ret = frescan_requests_get_data(*req, &req_data);
+        if (ret != 0) return ret;
+
+        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG,
+              "wait for a msg, net:%u chan:%u flags:%u\n",
+              net, recv_params[net].channel, recv_params[net].flags);
+
+        ret = frescan_recv(&recv_params[net],
+                            msg,
+                            sizeof(msg),
+                            &recv_bytes,
+                            &from,
+                            &prio);
+        if (ret != 0) return ret;
+
+        DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG,
+              "msg received, from:%u size:%u prio:%u\n",
+              from, recv_bytes, prio);
+
+        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);
@@ -282,197 +357,8 @@ int frescan_message_to_request(const uint8_t *msg,
                 case FRESCAN_REP_NEG:
                         return frescan_repneg_message_to_request(msg, req_data);
                 default:
-                        ERROR("request type not supported\n");
+                        ERROR("request type %X not supported\n",
+                              *(frescan_request_type_t *)msg);
                         return -1;
         }
 }
-
-/*
-
-int frescan_message_parse(frescan_network_t net,
-                          const uint8_t *msg,
-                          size_t size,
-                          frescan_node_t from)
-{
-        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(&params, 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;
-
-                default:
-                        ERROR("type not known %u\n", type);
-                        return -1;
-        }
-
-        return 0;
-}*/