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