]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_messages.c
renaming
[frescor/fna.git] / src_frescan / frescan_bwres_messages.c
1 /*!
2  * @file frescan_bwres_messages.c
3  *
4  * @brief FRESCAN bandwidth reservation layer: negotiation messages formating
5  *
6  * This module contains the data types that define the FRESCAN negotiation
7  * message format and operations to convert them into or from negotiation
8  * requests
9  *
10  * @version 0.01
11  *
12  * @date 2-Apr-2008
13  *
14  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
15  *
16  */
17
18 #include <string.h>
19 #include "frescan_bwres_messages.h"
20 #include "frescan_config.h"
21 #include "frescan_debug.h"
22 #include "frescan_requests.h"
23 #include "frescan_servers.h"
24
25 /**
26  *
27  *  NEG MESSAGE
28  *
29  *      1     2       N
30  *  +-----------------------+
31  *  | 'NEG' | ID | CONTRACT |
32  *  +-----------------------+
33  *
34  *  REP_NEG MESSAGE
35  *
36  *  +----------------------------------------+
37  *  | 'REPNEG' | ID | ACCEPTED | SC_CONTRACT |
38  *  +----------------------------------------+
39  *
40  *  RENEGOTIATE = NEG but with different type
41  *
42  *  CANCEL MESSAGE
43  *
44  *  +--------------------------------+
45  *  | 'CANCEL' | ID | CONTRACT_LABEL |
46  *  +--------------------------------+
47  *
48  *  REP_CANCEL MESSAGE
49  *
50  *  +---------------------------+
51  *  | 'REP_CANCEL' | ID | ERROR |
52  *  +---------------------------+
53  *
54  *  ID: the id of the request
55  *
56  */
57
58 typedef enum {
59         FRESCAN_MSG_TYPE_NEG        = 0,
60         FRESCAN_MSG_TYPE_RENEG      = 1,
61         FRESCAN_MSG_TYPE_CANCEL     = 2,
62         FRESCAN_MSG_TYPE_REP_NEG    = 3,
63         FRESCAN_MSG_TYPE_REP_RENEG  = 4,
64         FRESCAN_MSG_TYPE_REP_CANCEL = 5
65 } frescan_msg_type_t;
66
67 int frescan_neg_message_create(uint8_t *msg,
68                                frescan_request_id_t id,
69                                const frescan_contract_t *contract)
70 {
71         size_t num, bytes_written;
72         uint8_t *tmp = msg;
73
74         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
75               "creating a negotiation request message\n");
76
77         *tmp = (uint8_t)FRESCAN_MSG_TYPE_NEG;
78         tmp++;
79         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
80               "type: %d (1 byte)\n", FRESCAN_MSG_TYPE_NEG);
81
82         num = 2;
83         memcpy(tmp, &id, num);
84         tmp = tmp + num;
85         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
86               "request id: %d (2 bytes)\n", id);
87
88         num = sizeof(frescan_contract_t);
89         memcpy(tmp, contract, num);
90         tmp = tmp + num;
91
92         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
93               "contract (%d bytes)\n", num);
94
95         bytes_written = tmp - msg;
96
97         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
98               "total bytes_written: %d\n", bytes_written);
99
100         return (int)bytes_written;
101 }
102
103 int frescan_repneg_message_create(uint8_t *msg,
104                                   frescan_request_id_t id,
105                                   int accepted,
106                                   frescan_server_params_t *params)
107 {
108         size_t num, bytes_written;
109         uint8_t *tmp = msg;
110
111         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
112                 "creating a negotiation reply message\n");
113
114         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
115               "type: %d (1 byte)\n", FRESCAN_MSG_TYPE_REP_NEG);
116         *tmp = (uint8_t)FRESCAN_MSG_TYPE_REP_NEG;
117         tmp++;
118
119         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
120               "request id: %d (2 bytes)\n", id);
121         num = 2;
122         memcpy(tmp, &id, num);
123         tmp = tmp + num;
124
125         *tmp = (uint8_t)accepted;
126         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG, "accepted:%u\n", *tmp);
127         tmp++;
128
129         num = sizeof(frescan_budget_period_t);
130         memcpy(tmp, &params->values, num);
131         tmp = tmp + num;
132
133         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
134               "budget_period (%d bytes)\n", num);
135
136         num = 1;
137         memcpy(tmp, &params->prio, num);
138         tmp = tmp + num;
139
140         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
141               "server prio:%u\n", params->prio);
142
143         bytes_written = tmp - msg;
144
145         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
146               "total bytes_written: %d\n", bytes_written);
147
148         return (int)bytes_written;
149 }
150
151 int frescan_reneg_message_create(uint8_t *msg,
152                                  frescan_request_id_t id,
153                                  const frescan_contract_t *contract)
154 {
155         size_t num, bytes_written;
156         uint8_t *tmp = msg;
157
158         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
159               "creating a renegotiation request message\n");
160
161         *tmp = (uint8_t)FRESCAN_MSG_TYPE_RENEG;
162         tmp++;
163         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
164               "type: %d (1 byte)\n", FRESCAN_MSG_TYPE_RENEG);
165
166         num = 2;
167         memcpy(tmp, &id, num);
168         tmp = tmp + num;
169         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
170               "request id: %d (2 bytes)\n", id);
171
172         num = sizeof(frescan_contract_t);
173         memcpy(tmp, contract, num);
174         tmp = tmp + num;
175
176         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
177               "contract (%d bytes)\n", num);
178
179         // TODO: ADD server id? or look up the label??
180
181         bytes_written = tmp - msg;
182
183         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
184               "total bytes_written: %d\n", bytes_written);
185
186         return (int)bytes_written;
187 }
188
189 int frescan_message_parse(frescan_network_t net,
190                           const uint8_t *msg,
191                           size_t size,
192                           frescan_node_t from)
193 {
194         int ret;
195         frescan_msg_type_t type;
196         size_t num;
197         uint8_t *tmp;
198         frescan_contract_t contract;
199         frescan_request_id_t request_id;
200         frescan_robj_id_t reply;
201         uint8_t reply_msg[200];
202         int accepted;
203         frescan_neg_return_info_t *neg_return_info;
204         int bytes_to_send;
205         frescan_send_params_t params;
206         frescan_server_params_t server_params;
207
208         params.net = net;
209         params.channel = FRESCAN_NEG_CHANNEL;
210         params.flags = FRESCAN_SS | FRESCAN_ASYNC;
211         params.ss = the_networks[net].neg_messages_ss_id;
212         params.to  = from;
213
214         tmp = (uint8_t *)msg;
215         type = (frescan_msg_type_t)*msg;
216         tmp++;
217
218         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
219               "parsing message, type:%u, size:%u\n", type, size);
220
221         switch (type) {
222                 case FRESCAN_MSG_TYPE_NEG:
223                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
224                               "FRESCAN_MSG_TYPE_NEG\n");
225
226                         num = 2;
227                         memcpy(&request_id, tmp, num);
228                         tmp = tmp + num;
229                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
230                               "request id: %d (2 bytes)\n", request_id);
231
232                         num = sizeof(frescan_contract_t);
233                         memcpy(&contract, tmp, num);
234                         tmp = tmp + num;
235
236                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
237                               "contract (%d bytes)\n", num);
238
239                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
240                               "min_budget:%u max_period:(%u,%u)\n",
241                               contract.min_values.budget,
242                               contract.min_values.period.tv_sec,
243                               contract.min_values.period.tv_nsec);
244
245                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
246                               "max_budget:%u min_period:(%u,%u)\n",
247                               contract.max_values.budget,
248                               contract.max_values.period.tv_sec,
249                               contract.max_values.period.tv_nsec);
250
251                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
252                               "prio:%u\n", contract.prio);
253
254                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
255                               "TODO: sched test and add contract to table\n");
256 //                         accepted = 1;
257 //                         server_params.values.budget = contract.min_values.budget;
258 //                         server_params.values.period = contract.min_values.period;
259 //                         server_params.prio = contract.prio;
260                         FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
261                         accepted = 1;
262                         FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
263
264                         server_params.values.budget = 69;
265                         server_params.values.period.tv_sec = 33;
266                         server_params.values.period.tv_nsec = 666;
267                         server_params.prio = 2;
268
269                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
270                               "accepted:%u send results, net:%u to:%u ss:%u\n",
271                               accepted, params.net, params.to, params.ss);
272
273                         bytes_to_send = frescan_repneg_message_create
274                                                 (reply_msg,
275                                                 request_id,
276                                                 accepted,
277                                                 &server_params);
278
279                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
280                                 "bytes_to_send:%u\n", bytes_to_send);
281
282                         if (bytes_to_send <= 0) {
283                                 ERROR("creating reply_msg to neg\n");
284                                 return -1;
285                         }
286
287                         ret = frescan_send(&params, reply_msg, bytes_to_send);
288                         if (ret != 0) {
289                                 ERROR("error while sending neg request to master\n");
290                                 return ret;
291                         }
292                         break;
293
294                 case FRESCAN_MSG_TYPE_REP_NEG:
295                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
296                               "FRESCAN_MSG_TYPE_REP_NEG\n");
297
298                         num = 2;
299                         memcpy(&request_id, tmp, num);
300                         tmp = tmp + num;
301                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
302                               "request id: %d (2 bytes)\n", request_id);
303
304                         ret = frescan_request_get_return_info
305                                         (request_id,
306                                         (void *)&neg_return_info);
307                         if (ret != 0) {
308                                 ERROR("error getting final_values_ref\n");
309                                 return ret;
310                         }
311
312                         accepted = (int)*tmp;
313                         tmp++;
314
315                         if (accepted) {
316                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
317                                       "contract accepted:%d\n", accepted);
318                                 neg_return_info->error = 0;
319
320                                 num = sizeof(frescan_budget_period_t);
321                                 memcpy(&server_params.values, tmp, num);
322                                 tmp = tmp + num;
323
324                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
325                                       "final budget:%u period:(%u,%u)\n",
326                                       server_params.values.budget,
327                                       server_params.values.period.tv_sec,
328                                       server_params.values.period.tv_nsec);
329
330                                 num = 1;
331                                 memcpy(&server_params.prio, tmp, num);
332                                 tmp = tmp + num;
333
334                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
335                                       "server prio:%u\n", server_params.prio);
336
337                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
338                                       "create sporadic server with results\n");
339
340                                 ret = frescan_servers_create(net,
341                                                 &server_params,
342                                                 &neg_return_info->id);
343                                 if (ret != 0) {
344                                         ERROR("error creating server\n");
345                                         return ret;
346                                 }
347                         } else {
348                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
349                                       "contract not accepted:%d\n", accepted);
350                                 neg_return_info->error = -1;
351                         }
352
353                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
354                               "signal the request id with the results\n");
355
356                         ret = frescan_request_get_reply(request_id, &reply);
357                         if (ret != 0) {
358                                 ERROR("error getting reply object\n");
359                                 return ret;
360                         }
361
362                         ret = frescan_replyobject_signal(reply);
363                         if (ret != 0) {
364                                 ERROR("error while sending neg request to master\n");
365                                 return ret;
366                         }
367                         break;
368
369                 default:
370                         ERROR("type not known %u\n", type);
371                         return -1;
372         }
373
374         return 0;
375 }