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_bwres_analysis.h"
22 #include "frescan_data.h"
23 #include "frescan_debug.h"
24 #include "frescan_config.h"
25 #include "frescan_servers.h"
28 * frescan_bwres_init()
30 * Init the frescan bandwidth reservation layer
33 int frescan_bwres_init(frescan_network_t net)
36 frescan_server_params_t server_params; // TODO: improve this...
37 frescan_sa_init_params_t sa_init_params; // TODO: improve this...
39 sa_init_params.max_prio = 30;
40 sa_init_params.min_prio = 1;
42 ret = frescan_sa_init(&the_networks[net].scenario,
44 if (ret != 0) return ret;
46 server_params.values.budget = 5;
47 server_params.values.period.tv_sec = 1;
48 server_params.values.period.tv_nsec = 0;
49 server_params.prio = FRESCAN_BWRES_NEG_MESSAGES_PRIO;
51 ret = frescan_servers_create(net, &server_params,
52 &the_networks[net].neg_messages_ss_id);
53 if (ret != 0) return ret;
55 // TODO: we have to add this negotiation contracts to the sa table
57 ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
58 if (ret != 0) return ret;
60 ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
61 if (ret != 0) return ret;
63 ret = frescan_messages_init(net);
64 if (ret != 0) return ret;
66 ret = frescan_manager_thread_create(net);
67 if (ret != 0) return ret;
69 ret = frescan_acceptor_thread_create(net);
70 if (ret != 0) return ret;
76 * frescan_bwres_negotiate()
78 * to negotiate a contract we follow the next steps:
80 * 1.- prepare a request
81 * 2.- enqueue the request
82 * 3.- wait in the reply object for a reply
83 * 4.- return the final values and free the request
87 int frescan_bwres_negotiate(frescan_network_t net,
88 const frescan_contract_t *contract,
93 frescan_request_id_t req;
94 frescan_request_data_t *req_data;
95 frescan_server_params_t server_params;
97 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
99 ret = frescan_requests_alloc(&req);
100 if (ret != 0) return ret;
102 ret = frescan_requests_get_data(req, &req_data);
103 if (ret != 0) return ret;
105 req_data->type = FRESCAN_REQ_NEG;
107 req_data->contract = (frescan_contract_t *)contract;
108 req_data->request_node = the_networks[net].local_node;
111 ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
112 if (ret != 0) return ret;
114 // NOTE: we preallocate a server for the negotiation process
115 server_params.values.budget = contract->min_values.budget;
116 server_params.values.period = contract->min_values.period;
117 server_params.prio = contract->prio;
119 ret = frescan_servers_create(net, &server_params, &req_data->ss);
120 if (ret != 0) return ret;
122 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
124 ret = frescan_requests_enqueue(req);
125 if (ret != 0) return ret;
127 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
129 ret = frescan_bwres_robjs_wait(req_data->robj);
130 if (ret != 0) return ret;
132 ret = frescan_bwres_robjs_free(req_data->robj);
133 if (ret != 0) return ret;
135 switch (req_data->return_value) {
136 case FRESCAN_REQ_ACCEPTED:
137 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
140 server_params.prio = req_data->final_values.server_prio;
141 ret = frescan_servers_update(net, &server_params, *id);
142 if (ret != 0) return ret;
145 case FRESCAN_REQ_NOT_ACCEPTED:
146 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
148 ret = frescan_servers_destroy(net, req_data->ss);
149 if (ret != 0) return ret;
153 ERROR("return_value unknown\n");
157 frescan_requests_free(req);