2 * @file frescan_bwres_messages.c
4 * @brief FRESCAN bandwidth reservation layer: negotiation messages formating
6 * This module contains the data types that define the FRESCAN negotiation
7 * message format and operations to convert them into or from negotiation
14 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
18 * -----------------------------------------------------------------------
19 * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
21 * Universidad de Cantabria, SPAIN
22 * University of York, UK
23 * Scuola Superiore Sant'Anna, ITALY
24 * Kaiserslautern University, GERMANY
25 * Univ. Politécnica Valencia, SPAIN
26 * Czech Technical University in Prague, CZECH REPUBLIC
28 * Thales Communication S.A. FRANCE
29 * Visual Tools S.A. SPAIN
30 * Rapita Systems Ltd UK
33 * See http://www.frescor.org for a link to partners' websites
35 * FRESCOR project (FP6/2005/IST/5-034026) is funded
36 * in part by the European Union Sixth Framework Programme
37 * The European Union is not liable of any use that may be
40 * This file is part of FRESCAN
42 * FRESCAN is free software; you can redistribute it and/or modify
43 * it under the terms of the GNU General Public License as published by
44 * the Free Software Foundation; either version 2, or (at your option)
47 * FRESCAN is distributed in the hope that it will be useful, but
48 * WITHOUT ANY WARRANTY; without even the implied warranty of
49 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
50 * General Public License for more details.
52 * You should have received a copy of the GNU General Public License
53 * distributed with FRESCAN; see file COPYING. If not, write to the
54 * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
57 * As a special exception, including FRESCAN header files in a file,
58 * instantiating FRESCAN generics or templates, or linking other files
59 * with FRESCAN objects to produce an executable application, does not
60 * by itself cause the resulting executable application to be covered
61 * by the GNU General Public License. This exception does not
62 * however invalidate any other reasons why the executable file might be
63 * covered by the GNU Public License.
64 * -----------------------------------------------------------------------
69 #include "frescan_bwres_messages.h"
70 #include "frescan_bwres_requests.h"
72 #include "frescan_config.h"
73 #include "frescan_debug.h"
76 * frescan_messages_init()
79 static frescan_send_params_t send_params[FRESCAN_MX_NETWORKS];
80 static frescan_recv_params_t recv_params[FRESCAN_MX_NETWORKS];
82 int frescan_messages_init(frescan_network_t net)
84 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "initialization\n");
86 send_params[net].net = net;
87 send_params[net].channel = FRESCAN_NEG_CHANNEL;
88 send_params[net].flags = FRESCAN_SS | FRESCAN_ASYNC;
89 send_params[net].ss = the_networks[net].neg_messages_ss_id;
90 send_params[net].to = FRESCAN_NEG_MASTER_NODE;
92 recv_params[net].net = net;
93 recv_params[net].channel = FRESCAN_NEG_CHANNEL;
94 recv_params[net].flags = FRESCAN_SYNC;
101 * FRESCAN_REQ_NEG MESSAGE
102 * =======================
103 * This message is sent from a SLAVE to the MASTER when the slave wants
104 * to negotiate a new contract. It contains the type (a negotiation 'NEG'
105 * request), the LOCAL request id (so the MASTER can use it in the reply
106 * to identify to which request is replying), a preallocated sporadic
107 * server id (the MASTER will store it in its table together with the
108 * node so we can perform renegotiations and spare capacity distribution
109 * in the future) and the contract.
112 * +-----------------------------+
113 * | 'NEG' | REQ | SS | CONTRACT |
114 * +-----------------------------+
118 struct frescan_req_neg_message_t {
119 frescan_request_type_t type;
120 frescan_request_id_t req;
122 frescan_contract_t contract;
123 } __attribute__ ((packed));
125 static int frescan_request_to_neg_message(const frescan_request_data_t *data,
128 struct frescan_req_neg_message_t *neg_msg;
130 neg_msg = (struct frescan_req_neg_message_t *)msg;
132 neg_msg->type = FRESCAN_REQ_NEG;
133 neg_msg->req = data->req;
134 neg_msg->ss = data->ss;
135 neg_msg->contract = *(data->contract);
137 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
138 neg_msg->type, neg_msg->req, neg_msg->ss);
140 return sizeof(struct frescan_req_neg_message_t);
143 static int frescan_neg_message_to_request(const uint8_t *msg,
144 frescan_request_data_t *data)
146 struct frescan_req_neg_message_t *neg_msg;
148 neg_msg = (struct frescan_req_neg_message_t *)msg;
150 data->type = FRESCAN_REQ_NEG;
151 data->req = neg_msg->req;
152 data->ss = neg_msg->ss;
153 *(data->contract) = neg_msg->contract;
155 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
156 data->type, data->req, data->ss);
163 * FRESCAN_REQ_RENEG MESSAGE
164 * =========================
165 * This message is sent from a SLAVE to the MASTER when the slave wants
166 * to renegotiate a contract. It contains the type (a renegotiation 'RENEG'
167 * request), the LOCAL request id (so the MASTER can use it in the reply
168 * to identify to which request is replying), the sporadic server id
169 * (the MASTER will look up its table together with the node to find the
170 * appropiate entry) and the contract.
173 * +-------------------------------+
174 * | 'RENEG' | REQ | SS | CONTRACT |
175 * +-------------------------------+
179 struct frescan_req_reneg_message_t {
180 frescan_request_type_t type;
181 frescan_request_id_t req;
183 frescan_contract_t contract;
184 } __attribute__ ((packed));
186 static int frescan_request_to_reneg_message(const frescan_request_data_t *data,
189 struct frescan_req_reneg_message_t *reneg_msg;
191 reneg_msg = (struct frescan_req_reneg_message_t *)msg;
193 reneg_msg->type = FRESCAN_REQ_RENEG;
194 reneg_msg->req = data->req;
195 reneg_msg->ss = data->ss;
196 reneg_msg->contract = *(data->contract);
198 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
199 reneg_msg->type, reneg_msg->req, reneg_msg->ss);
201 return sizeof(struct frescan_req_reneg_message_t);
204 static int frescan_reneg_message_to_request(const uint8_t *msg,
205 frescan_request_data_t *data)
207 struct frescan_req_reneg_message_t *reneg_msg;
209 reneg_msg = (struct frescan_req_reneg_message_t *)msg;
211 data->type = FRESCAN_REQ_RENEG;
212 data->req = reneg_msg->req;
213 data->ss = reneg_msg->ss;
214 *(data->contract) = reneg_msg->contract;
216 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ss:%d\n",
217 data->type, data->req, data->ss);
223 * FRESCAN_REQ_CANCEL MESSAGE
224 * ==========================
225 * This message is sent from a SLAVE to the MASTER to cancel a contract.
226 * It contains the type, 'CANCEL' and the sporadic server id (the MASTER will
227 * have to look it up in the table). The MASTER doesnt need to reply this
236 struct frescan_req_cancel_message_t {
237 frescan_request_type_t type;
239 } __attribute__ ((packed));
241 static int frescan_request_to_cancel_message(const frescan_request_data_t *data,
244 struct frescan_req_cancel_message_t *cancel_msg;
246 cancel_msg = (struct frescan_req_cancel_message_t *)msg;
248 cancel_msg->type = FRESCAN_REQ_CANCEL;
249 cancel_msg->ss = data->ss;
251 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
252 cancel_msg->type, cancel_msg->ss);
254 return sizeof(struct frescan_req_cancel_message_t);
257 static int frescan_cancel_message_to_request(const uint8_t *msg,
258 frescan_request_data_t *data)
260 struct frescan_req_cancel_message_t *cancel_msg;
262 cancel_msg = (struct frescan_req_cancel_message_t *)msg;
264 data->type = FRESCAN_REQ_CANCEL;
265 data->ss = cancel_msg->ss;
267 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d ss:%d\n",
268 data->type, data->ss);
275 * FRESCAN_REP_NEG MESSAGE
276 * =======================
277 * This message is sent from the MASTER to a slave as a reply to a
278 * FRESCAN_REQ_NEG or a FRESCAN_REQ_RENEG, to say if they were admited.
279 * It contains the type 'REPNEG', the request ID of the slave, a
280 * return value to say if the contract is admited or not, and the final
281 * values if it was admited
283 * +----------------------------------------------+
284 * | 'REPNEG' | REQ | RETURN_VALUE | FINAL_VALUES |
285 * +----------------------------------------------+
289 struct frescan_rep_neg_message_t {
290 frescan_request_type_t type;
291 frescan_request_id_t req;
292 frescan_request_retval_t return_value;
293 frescan_sa_final_values_t final_values;
294 } __attribute__ ((packed));
296 static int frescan_request_to_repneg_message(const frescan_request_data_t *data,
299 struct frescan_rep_neg_message_t *repneg_msg;
301 repneg_msg = (struct frescan_rep_neg_message_t *)msg;
303 repneg_msg->type = FRESCAN_REP_NEG;
304 repneg_msg->req = data->req;
305 repneg_msg->return_value = data->return_value;
306 repneg_msg->final_values = data->final_values;
308 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
309 repneg_msg->type, repneg_msg->req, repneg_msg->return_value);
311 return sizeof(struct frescan_rep_neg_message_t);
314 static int frescan_repneg_message_to_request(const uint8_t *msg,
315 frescan_request_data_t *data)
317 struct frescan_rep_neg_message_t *repneg_msg;
319 repneg_msg = (struct frescan_rep_neg_message_t *)msg;
321 data->type = FRESCAN_REP_NEG;
322 data->req = repneg_msg->req;
323 data->return_value = repneg_msg->return_value;
324 data->final_values = repneg_msg->final_values;
326 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "type:%d req:%d ret:%d\n",
327 data->type, data->req, data->return_value);
333 * frescan_messages_send_request()
335 * this function converts a request with the necessary data into a message
338 * @req_data: the request to be sent (NOTE: the network is in req_data)
342 int frescan_messages_send_request(const frescan_request_data_t *req_data)
345 uint8_t msg[2000]; // TODO: use a constant for max neg message size
348 switch(req_data->type) {
349 case FRESCAN_REQ_NEG:
350 size = frescan_request_to_neg_message(req_data, msg);
351 send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
353 case FRESCAN_REQ_RENEG:
354 size = frescan_request_to_reneg_message(req_data, msg);
355 send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
357 case FRESCAN_REQ_CANCEL:
358 size = frescan_request_to_cancel_message(req_data, msg);
359 send_params[req_data->net].to = FRESCAN_NEG_MASTER_NODE;
361 case FRESCAN_REP_NEG:
362 size = frescan_request_to_repneg_message(req_data, msg);
363 send_params[req_data->net].to = req_data->request_node;
366 ERROR("request type not supported\n");
370 ret = frescan_send(&send_params[req_data->net], msg, size);
371 if (ret != 0) return ret;
373 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG, "sent request, type:%X size:%d\n",
374 *(frescan_request_type_t *)msg, size);
380 * frescan_messages_recv_request()
382 * this function BLOCKS the calling thread until receives a message
383 * and transforms it into a request.
385 * @req_data: the request data to fill from the message bytes (out)
389 int frescan_messages_recv_request(frescan_network_t net,
390 frescan_request_id_t *req)
393 uint8_t msg[2000]; // TODO: use a constant with the max neg message size
397 frescan_request_data_t *req_data;
399 ret = frescan_requests_alloc(req);
400 if (ret != 0) return ret;
402 ret = frescan_requests_get_data(*req, &req_data);
403 if (ret != 0) return ret;
405 ret = frescan_recv(&recv_params[net],
411 if (ret != 0) return ret;
413 DEBUG(FRESCAN_MESSAGES_ENABLE_DEBUG,
414 "msg received! from:%u size:%u prio:%u chan:%u flags:%X\n",
415 from, recv_bytes, prio, recv_params[net].channel,
416 recv_params[net].flags);
418 req_data->request_node = from;
421 switch(*((frescan_request_type_t *)msg)) {
422 case FRESCAN_REQ_NEG:
423 return frescan_neg_message_to_request(msg, req_data);
424 case FRESCAN_REQ_RENEG:
425 return frescan_reneg_message_to_request(msg, req_data);
426 case FRESCAN_REQ_CANCEL:
427 return frescan_cancel_message_to_request(msg, req_data);
428 case FRESCAN_REP_NEG:
429 return frescan_repneg_message_to_request(msg, req_data);
431 ERROR("request type %X not supported\n",
432 *(frescan_request_type_t *)msg);