2 * @file frescan_bwres.c
4 * @brief FRESCAN bandwidth reservation layer
6 * This module contains function to negotiate contracts and get the
7 * corresponding frescan sporadic servers.
13 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
17 #include "frescan_bwres.h"
18 #include "frescan_bwres_requests.h"
19 #include "frescan_bwres_messages.h"
20 #include "frescan_bwres_threads.h"
21 #include "frescan_data.h"
22 #include "frescan_debug.h"
23 #include "frescan_config.h"
24 #include "frescan_servers.h"
27 * frescan_bwres_init()
29 * Init the frescan bandwidth reservation layer
32 int frescan_bwres_init(frescan_network_t net)
35 frescan_server_params_t params;
37 // TODO: server params must be configurable
38 // TODO: initialization tree like in DTM
39 params.values.budget = 5;
40 params.values.period.tv_sec = 1;
41 params.values.period.tv_nsec = 0;
42 params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
44 ret = frescan_servers_create(net, ¶ms,
45 &the_networks[net].neg_messages_ss_id);
46 if (ret != 0) return ret;
48 ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
49 if (ret != 0) return ret;
51 ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
52 if (ret != 0) return ret;
54 ret = frescan_messages_init(net);
55 if (ret != 0) return ret;
57 ret = frescan_manager_thread_create(net);
58 if (ret != 0) return ret;
60 ret = frescan_acceptor_thread_create(net);
61 if (ret != 0) return ret;
67 * frescan_bwres_negotiate()
69 * to negotiate a contract we follow the next steps:
71 * 1.- prepare a request
72 * 2.- enqueue the request
73 * 3.- wait in the reply object for a reply
74 * 4.- return the final values and free the request
78 int frescan_bwres_negotiate(frescan_network_t net,
79 const frescan_contract_t *contract,
83 frescan_request_id_t req;
84 frescan_request_data_t *req_data;
85 frescan_server_params_t server_params;
87 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
89 ret = frescan_requests_alloc(&req);
90 if (ret != 0) return ret;
92 ret = frescan_requests_get_data(req, &req_data);
93 if (ret != 0) return ret;
95 req_data->type = FRESCAN_REQ_NEG;
97 req_data->contract = (frescan_contract_t *)contract;
98 req_data->request_node = the_networks[net].local_node;
101 ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
102 if (ret != 0) return ret;
104 // NOTE: we preallocate a server for the negotiation process
105 server_params.values.budget = contract->min_values.budget;
106 server_params.values.period = contract->min_values.period;
107 server_params.prio = contract->prio;
109 ret = frescan_servers_create(net, &server_params, &req_data->ss);
110 if (ret != 0) return ret;
112 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
114 ret = frescan_requests_enqueue(req);
115 if (ret != 0) return ret;
117 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
119 ret = frescan_bwres_robjs_wait(req_data->robj);
120 if (ret != 0) return ret;
122 ret = frescan_bwres_robjs_free(req_data->robj);
123 if (ret != 0) return ret;
125 switch (req_data->return_value) {
126 case FRESCAN_REQ_ACCEPTED:
127 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
132 case FRESCAN_REQ_NOT_ACCEPTED:
133 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
134 ret = frescan_servers_destroy(net, req_data->ss);
135 if (ret != 0) return ret;
139 case FRESCAN_REQ_ERROR:
140 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation ERROR\n");
141 ret = frescan_servers_destroy(net, req_data->ss);
142 if (ret != 0) return ret;
147 ERROR("return_value unknown\n");
151 frescan_requests_free(req);
153 return ret; // TODO: distinguish errors and failed negotiations