]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres.c
add the infraestructure for storing the negotiated contracts and performing the analy...
[frescor/fna.git] / src_frescan / frescan_bwres.c
1 /*!
2  * @file frescan_bwres.c
3  *
4  * @brief FRESCAN bandwidth reservation layer
5  *
6  * This module contains function to negotiate contracts and get the
7  * corresponding frescan sporadic servers.
8  *
9  * @version 0.01
10  *
11  * @date 1-Apr-2008
12  *
13  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
14  *
15  */
16
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"
26
27 /**
28  * frescan_bwres_init()
29  *
30  * Init the frescan bandwidth reservation layer
31  */
32
33 int frescan_bwres_init(frescan_network_t net)
34 {
35         int ret;
36         frescan_server_params_t  server_params;  // TODO: improve this...
37         frescan_sa_init_params_t sa_init_params; // TODO: improve this...
38
39         sa_init_params.max_prio = 30;
40         sa_init_params.min_prio = 1;
41
42         ret = frescan_sa_init(&the_networks[net].scenario,
43                               &sa_init_params);
44         if (ret != 0) return ret;
45
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;
50
51         ret = frescan_servers_create(net, &server_params,
52                                      &the_networks[net].neg_messages_ss_id);
53         if (ret != 0) return ret;
54
55         // TODO: we have to add this negotiation contracts to the sa table
56
57         ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
58         if (ret != 0) return ret;
59
60         ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
61         if (ret != 0) return ret;
62
63         ret = frescan_messages_init(net);
64         if (ret != 0) return ret;
65
66         ret = frescan_manager_thread_create(net);
67         if (ret != 0) return ret;
68
69         ret = frescan_acceptor_thread_create(net);
70         if (ret != 0) return ret;
71
72         return 0;
73 }
74
75 /**
76  * frescan_bwres_negotiate()
77  *
78  * to negotiate a contract we follow the next steps:
79  *
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
84  *
85  */
86
87 int frescan_bwres_negotiate(frescan_network_t net,
88                             const frescan_contract_t *contract,
89                             frescan_ss_t *id,
90                             bool *accepted)
91 {
92         int ret;
93         frescan_request_id_t   req;
94         frescan_request_data_t *req_data;
95         frescan_server_params_t server_params;
96
97         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
98
99         ret = frescan_requests_alloc(&req);
100         if (ret != 0) return ret;
101
102         ret = frescan_requests_get_data(req, &req_data);
103         if (ret != 0) return ret;
104
105         req_data->type         = FRESCAN_REQ_NEG;
106         req_data->req          = req;
107         req_data->contract     = (frescan_contract_t *)contract;
108         req_data->request_node = the_networks[net].local_node;
109         req_data->net          = net;
110
111         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
112         if (ret != 0) return ret;
113
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;
118
119         ret = frescan_servers_create(net, &server_params, &req_data->ss);
120         if (ret != 0) return ret;
121
122         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
123
124         ret = frescan_requests_enqueue(req);
125         if (ret != 0) return ret;
126
127         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
128
129         ret = frescan_bwres_robjs_wait(req_data->robj);
130         if (ret != 0) return ret;
131
132         ret = frescan_bwres_robjs_free(req_data->robj);
133         if (ret != 0) return ret;
134
135         switch (req_data->return_value) {
136                 case FRESCAN_REQ_ACCEPTED:
137                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
138                         *accepted = true;
139                         *id = req_data->ss;
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;
143                         break;
144
145                 case FRESCAN_REQ_NOT_ACCEPTED:
146                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation FAIL\n");
147                         *accepted = false;
148                         ret = frescan_servers_destroy(net, req_data->ss);
149                         if (ret != 0) return ret;
150                         break;
151
152                 default:
153                         ERROR("return_value unknown\n");
154                         return -1;
155         }
156
157         frescan_requests_free(req);
158         return 0;
159 }