]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres.c
875138f1324bd0ddeeb8a166d3c811b4b36e97f0
[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_data.h"
22 #include "frescan_debug.h"
23 #include "frescan_config.h"
24 #include "frescan_servers.h"
25
26 /**
27  * frescan_bwres_init()
28  *
29  * Init the frescan bandwidth reservation layer
30  */
31
32 int frescan_bwres_init(frescan_network_t net)
33 {
34         int ret;
35         frescan_server_params_t params;
36
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;
43
44         ret = frescan_servers_create(net, &params,
45                                      &the_networks[net].neg_messages_ss_id);
46         if (ret != 0) return ret;
47
48         ret = frescan_bwres_robjs_init(FRESCAN_REPLY_OBJECTS_MX_CEILING);
49         if (ret != 0) return ret;
50
51         ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
52         if (ret != 0) return ret;
53
54         ret = frescan_messages_init(net);
55         if (ret != 0) return ret;
56
57         ret = frescan_manager_thread_create(net);
58         if (ret != 0) return ret;
59
60         ret = frescan_acceptor_thread_create(net);
61         if (ret != 0) return ret;
62
63         return 0;
64 }
65
66 /**
67  * frescan_bwres_negotiate()
68  *
69  * to negotiate a contract we follow the next steps:
70  *
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
75  *
76  */
77
78 int frescan_bwres_negotiate(frescan_network_t net,
79                             const frescan_contract_t *contract,
80                             frescan_ss_t *id)
81 {
82         int ret;
83         frescan_request_id_t   req;
84         frescan_request_data_t *req_data;
85         frescan_server_params_t server_params;
86
87         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "preparing a negotiation request\n");
88
89         ret = frescan_requests_alloc(&req);
90         if (ret != 0) return ret;
91
92         ret = frescan_requests_get_data(req, &req_data);
93         if (ret != 0) return ret;
94
95         req_data->type         = FRESCAN_REQ_NEG;
96         req_data->req          = req;
97         req_data->contract     = (frescan_contract_t *)contract;
98         req_data->request_node = the_networks[net].local_node;
99         req_data->net          = net;
100
101         ret = frescan_bwres_robjs_alloc(&req_data->robj, FRESCAN_BWRES_MX_PRIO);
102         if (ret != 0) return ret;
103
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;
108
109         ret = frescan_servers_create(net, &server_params, &req_data->ss);
110         if (ret != 0) return ret;
111
112         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "enqueue the negotiation request\n");
113
114         ret = frescan_requests_enqueue(req);
115         if (ret != 0) return ret;
116
117         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait for a reply\n");
118
119         ret = frescan_bwres_robjs_wait(req_data->robj);
120         if (ret != 0) return ret;
121
122         ret = frescan_bwres_robjs_free(req_data->robj);
123         if (ret != 0) return ret;
124
125         switch (req_data->return_value) {
126                 case FRESCAN_REQ_ACCEPTED:
127                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "negotiation OK\n");
128                         *id = req_data->ss;
129                         ret = 0;
130                         break;
131
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;
136                         ret = -1;
137                         break;
138
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;
143                         ret = -1;
144                         break;
145
146                 default:
147                         ERROR("return_value unknown\n");
148                         return -1;
149         }
150
151         frescan_requests_free(req);
152
153         return ret; // TODO: distinguish errors and failed negotiations
154 }