]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_negotiation_messages.c
1bc8a00ea9b68342e981d60fe6974967719a377d
[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                         FRESCAN_ACQUIRE_LOCK(&the_networks[net].lock);
222                         accepted = 1;
223                         FRESCAN_RELEASE_LOCK(&the_networks[net].lock);
224
225                         server_params.values.budget = 69;
226                         server_params.values.period.tv_sec = 33;
227                         server_params.values.period.tv_nsec = 666;
228                         server_params.prio = 2;
229
230                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
231                               "accepted:%u send results, net:%u to:%u ss:%u\n",
232                               accepted, params.net, params.to, params.ss);
233
234                         bytes_to_send = frescan_repneg_message_create
235                                                 (reply_msg,
236                                                 request_id,
237                                                 accepted,
238                                                 &server_params);
239
240                         DEBUG(FRESCAN_BWRES_ENABLE_DEBUG,
241                                 "bytes_to_send:%u\n", bytes_to_send);
242
243                         if (bytes_to_send <= 0) {
244                                 ERROR("creating reply_msg to neg\n");
245                                 return -1;
246                         }
247
248                         ret = frescan_send(&params, reply_msg, bytes_to_send);
249                         if (ret != 0) {
250                                 ERROR("error while sending neg request to master\n");
251                                 return ret;
252                         }
253                         break;
254
255                 case FRESCAN_MSG_TYPE_REP_NEG:
256                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
257                               "FRESCAN_MSG_TYPE_REP_NEG\n");
258
259                         num = 2;
260                         memcpy(&request_id, tmp, num);
261                         tmp = tmp + num;
262                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
263                               "request id: %d (2 bytes)\n", request_id);
264
265                         ret = frescan_request_get_return_info
266                                         (request_id,
267                                         (void *)&neg_return_info);
268                         if (ret != 0) {
269                                 ERROR("error getting final_values_ref\n");
270                                 return ret;
271                         }
272
273                         accepted = (int)*tmp;
274                         tmp++;
275
276                         if (accepted) {
277                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
278                                       "contract accepted:%d\n", accepted);
279                                 neg_return_info->error = 0;
280
281                                 num = sizeof(frescan_budget_period_t);
282                                 memcpy(&server_params.values, tmp, num);
283                                 tmp = tmp + num;
284
285                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
286                                       "final budget:%u period:(%u,%u)\n",
287                                       server_params.values.budget,
288                                       server_params.values.period.tv_sec,
289                                       server_params.values.period.tv_nsec);
290
291                                 num = 1;
292                                 memcpy(&server_params.prio, tmp, num);
293                                 tmp = tmp + num;
294
295                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
296                                       "server prio:%u\n", server_params.prio);
297
298                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
299                                       "create sporadic server with results\n");
300
301                                 ret = frescan_servers_create(net,
302                                                 &server_params,
303                                                 &neg_return_info->id);
304                                 if (ret != 0) {
305                                         ERROR("error creating server\n");
306                                         return ret;
307                                 }
308                         } else {
309                                 DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
310                                       "contract not accepted:%d\n", accepted);
311                                 neg_return_info->error = -1;
312                         }
313
314                         DEBUG(FRESCAN_NEG_MESSAGES_ENABLE_DEBUG,
315                               "signal the request id with the results\n");
316
317                         ret = frescan_request_get_reply(request_id, &reply);
318                         if (ret != 0) {
319                                 ERROR("error getting reply object\n");
320                                 return ret;
321                         }
322
323                         ret = frescan_replyobject_signal(reply);
324                         if (ret != 0) {
325                                 ERROR("error while sending neg request to master\n");
326                                 return ret;
327                         }
328                         break;
329
330                 default:
331                         ERROR("type not known %u\n", type);
332                         return -1;
333         }
334
335         return 0;
336 }