]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bandwidth_reservation.c
28bec59cc3fdf5ea78d91bf23fe1f8f3377cc19a
[frescor/fna.git] / src_frescan / frescan_bandwidth_reservation.c
1 /*!
2  * @file frescan_bandwidth_reservation.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_bandwidth_reservation.h"
18 #include "frescan_data.h"
19 #include "frescan_requests_queue.h"    // frescan_requests_init
20 #include "frescan_negotiator_thread.h" // frescan_negotiator_thread_create
21 #include "frescan_debug.h"
22 #include "frescan_config.h"
23 #include "frescan_acceptor_threads.h"
24 #include "frescan_servers.h"
25 #include "frescan_negotiation_messages.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 params;
37
38         // TODO: server params must be configurable
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) {
47                 ERROR("could not create server for negotiation messages\n");
48                 return ret;
49         }
50
51         ret = frescan_requests_init(FRESCAN_REQUESTS_MX_CEILING);
52         if (ret != 0) {
53                 ERROR("could not initialize the requests\n");
54                 return ret;
55         }
56
57         if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
58                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "i am master node (%u)\n",
59                       the_networks[net].local_node);
60                 ret = frescan_negotiator_thread_create(net);
61                 if (ret != 0) {
62                         ERROR("could not initialize the negotiator thread\n");
63                         return ret;
64                 }
65         } else {
66                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "i am a slave node (%u)\n",
67                       the_networks[net].local_node);
68         }
69
70         ret = frescan_acceptor_thread_create(net);
71         if (ret != 0) {
72                 ERROR("could not create acceptor thread\n");
73                 return ret;
74         }
75
76         return 0;
77 }
78
79 /**
80  * frescan_bwres_negotiate()
81  *
82  * negotiate a contract. For that we allocate a reply object and then
83  * we enqueue our request in the master's requests queue (which can be
84  * local or require a network message)
85  */
86
87 int frescan_bwres_negotiate(frescan_network_t net,
88                             const frescan_contract_t *contract,
89                             frescan_ss_t *id)
90 {
91         int ret;
92         frescan_robj_id_t reply;
93         frescan_request_id_t request;
94         frescan_neg_return_info_t return_info;
95         uint8_t msg[200];
96         int size;
97         frescan_send_params_t params;
98
99         ret = frescan_replyobject_alloc(&reply, FRESCAN_BWRES_MX_PRIO);
100         if (ret != 0) {
101                 ERROR("could not allocate reply object\n");
102                 return ret;
103         }
104
105         ret = frescan_request_alloc(&request);
106         if (ret != 0) {
107                 ERROR("could not allocate request\n");
108                 return ret;
109         }
110
111         ret = frescan_request_set_return_info(request,
112                                               (void *) &return_info);
113         if (ret != 0) {
114                 ERROR("could not set return_info pointer\n");
115                 return ret;
116         }
117
118         ret = frescan_request_set_reply(request, reply);
119         if (ret != 0) {
120                 ERROR("could not set reply\n");
121                 return ret;
122         }
123
124         if (the_networks[net].local_node == FRESCAN_NEG_MASTER_NODE) {
125                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
126                       "I am master, negotiation in local node\n");
127
128                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
129                       "set FRESCAN_NEGOTIATE type: %d\n", FRESCAN_NEGOTIATE);
130
131                 ret = frescan_request_set_type(request, FRESCAN_NEGOTIATE);
132                 if (ret != 0) {
133                         ERROR("could not set type\n");
134                         return ret;
135                 }
136
137                 ret = frescan_request_set_contract(request, contract);
138                 if (ret != 0) {
139                         ERROR("could not set contract\n");
140                         return ret;
141                 }
142
143                 ret = frescan_request_set_src(request, FRESCAN_NEG_MASTER_NODE);
144                 if (ret != 0) {
145                         ERROR("could not set src\n");
146                         return ret;
147                 }
148
149                 ret = frescan_requestqueue_enqueue(request);
150                 if (ret != 0) {
151                         ERROR("could not enqueue the request\n");
152                         return ret;
153                 }
154         } else {
155                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
156                       "I am slave, negotiation in master node\n");
157
158                 size = frescan_neg_message_create(msg, request, contract);
159
160                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
161                       "created a neg message, size: %d\n", size);
162
163                 params.net = net;
164                 params.to  = FRESCAN_NEG_MASTER_NODE;
165                 params.channel = FRESCAN_NEG_CHANNEL;
166
167 //                 params.flags = FRESCAN_FP | FRESCAN_ASYNC;
168 //                 params.prio = 8;
169                 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
170                 params.ss = the_networks[net].neg_messages_ss_id;
171
172                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
173                       "send msg to master, net:%u to:%u ss:%u\n",
174                       params.net, params.to, params.ss);
175
176                 ret = frescan_send(&params, msg, size);
177                 if (ret != 0) {
178                         ERROR("error while sending neg request to master\n");
179                         return ret;
180                 }
181         }
182
183         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG, "wait on reply object\n");
184
185         ret = frescan_replyobject_wait(reply);
186         if (ret != 0) {
187                 ERROR("error while waiting on the reply object\n");
188                 return ret;
189         }
190
191         ret = frescan_replyobject_free(reply);
192         if (ret != 0) {
193                 ERROR("could not free reply object\n");
194                 return ret;
195         }
196
197         if (return_info.error) {
198                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
199                       "negotiation was not accepted, error:%d\n",
200                       return_info.error);
201         } else {
202                 DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
203                       "negotiation finished succesfully ss:%d\n",
204                       return_info.id);
205         }
206
207         *id = return_info.id;
208
209         ret = frescan_request_free(request);
210         if (ret != 0) {
211                 ERROR("could not free request\n");
212                 return ret;
213         }
214
215         return return_info.error;
216 }