2 * @file frescan_bwres_fna.c
4 * @brief FRESCAN bandwidth reservation layer: FNA hooks
6 * This module contains hooks to integrate the FRESCAN protocol in FRSH
12 * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
16 * -----------------------------------------------------------------------
17 * Copyright (C) 2006 - 2008 FRESCOR consortium partners:
19 * Universidad de Cantabria, SPAIN
20 * University of York, UK
21 * Scuola Superiore Sant'Anna, ITALY
22 * Kaiserslautern University, GERMANY
23 * Univ. Politécnica Valencia, SPAIN
24 * Czech Technical University in Prague, CZECH REPUBLIC
26 * Thales Communication S.A. FRANCE
27 * Visual Tools S.A. SPAIN
28 * Rapita Systems Ltd UK
31 * See http://www.frescor.org for a link to partners' websites
33 * FRESCOR project (FP6/2005/IST/5-034026) is funded
34 * in part by the European Union Sixth Framework Programme
35 * The European Union is not liable of any use that may be
38 * This file is part of FRESCAN
40 * FRESCAN is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License as published by
42 * the Free Software Foundation; either version 2, or (at your option)
45 * FRESCAN is distributed in the hope that it will be useful, but
46 * WITHOUT ANY WARRANTY; without even the implied warranty of
47 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
48 * General Public License for more details.
50 * You should have received a copy of the GNU General Public License
51 * distributed with FRESCAN; see file COPYING. If not, write to the
52 * Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
55 * As a special exception, including FRESCAN header files in a file,
56 * instantiating FRESCAN generics or templates, or linking other files
57 * with FRESCAN objects to produce an executable application, does not
58 * by itself cause the resulting executable application to be covered
59 * by the GNU General Public License. This exception does not
60 * however invalidate any other reasons why the executable file might be
61 * covered by the GNU Public License.
62 * -----------------------------------------------------------------------
66 #include <math.h> /* ceil */
68 #include "frsh.h" /* frsh_resource_id_t, .. */
69 #include "frescan.h" /* frescan_init, ... */
70 #include "frescan_data.h" /* frescan_contract_t, ... */
71 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
72 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
75 #include "frescan_debug.h" /* DEBUG, ERROR */
77 //////////////////////////////////////////////////////////////////////
79 //////////////////////////////////////////////////////////////////////
84 * This function will be hooked to the frsh_init function and it is
85 * intented to initialize the protocol and its structures.
87 * @param[in] resource_id The network we are referring to (a protocol
88 * could be able to handle several networks at the same time)
91 * 0 if there are no errors \n
92 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
93 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
94 * FNA_ERR_ALREADY_INITIALIZED:
95 * if the function has already been called before (with success) \n
98 int frescan_fna_init(const frsh_resource_id_t resource_id)
101 frescan_init_params_t init_params;
103 // TODO: resource_id must be relative or sth
104 // TODO: init_params must be configurable
105 init_params.net = (frescan_network_t)resource_id;
106 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
107 init_params.tx_fp_max_prio = 10;
108 init_params.rx_num_of_channels = 10;
109 init_params.rx_channel_max_prio = NULL;
111 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
113 ret = frescan_init(&init_params);
114 if (ret != 0) ERROR ("could not init FRESCAN");
116 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
118 ret = frescan_bwres_init(init_params.net);
119 if (ret != 0) ERROR ("could not init BWRES");
124 ///////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////
129 * frescan_fna_contract_negotiate()
131 * The operation negotiates a contract and if accepted it will return
132 * a fna_vres_id_t. It will also check that the given contract_id is unique
133 * within the network.
135 * If the on-line admission test is enabled, it determines whether the
136 * contract can be admitted or not based on the current contracts
137 * established in the network. Then it creates the vres and
138 * recalculates all necessary parameters for the contracts already
139 * present in the system.
141 * This is a potentially blocking operation, it returns when the
142 * system has either rejected the contract, or admitted it and made it
145 * @param[in] resource_id The network we are referring to (a protocol
146 * could be able to handle several networks at the same time)
147 * @param[in] contract The contract parameters to negotiate
148 * @param[out] vres The internal virtual resource id
151 * 0 if there are no errors (in this case it also means contract accepted) \n
152 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
153 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
154 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
155 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
156 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
157 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
158 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
161 int frescan_fna_contract_negotiate
162 (const frsh_resource_id_t resource_id,
163 const frsh_contract_t *contract,
169 frescan_contract_t frescan_contract;
171 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
172 "frsh contract->frescan contract\n");
174 // NOTE: budget is stored as number of can frames in tv_sec
175 frescan_contract.min_values.budget = contract->budget_min.tv_sec;
176 frescan_contract.min_values.period = contract->period_max;
178 frescan_contract.max_values.budget = contract->budget_max.tv_sec;
179 frescan_contract.max_values.period = contract->period_min;
181 // TODO: put 0 if we want the sa module to assign the prios
182 frescan_contract.prio = contract->preemption_level;
184 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
185 ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
189 if (ret != 0) return -1;
191 if (accepted == true) {
192 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
193 *vres = (fna_vres_id_t)ss;
196 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
197 return -1; // TODO: change to constant FNA_REJECTED
202 * frescan_fna_contract_renegotiate_sync()
204 * The operation renegotiates a contract for an existing vres. If
205 * the on-line admission test is enabled it determines whether the
206 * contract can be admitted or not based on the current contracts
207 * established in the system. If it cannot be admitted, the old
208 * contract remains in effect and an error is returned. If it can be
209 * admitted, it recalculates all necessary parameters for the
210 * contracts already present in the system and returns zero. This is a
211 * potentially blocking operation; it returns when the system has
212 * either rejected the new contract, or admitted it and made it
215 * @param[in] resource_id The network we are referring to (a protocol
216 * could be able to handle several networks at the same time)
217 * @param[in] vres The internal virtual resource id to renegotiate
218 * @param[in] new_contract The new contract
221 * 0 if there are no errors (in this case it also means contract accepted) \n
222 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
223 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
224 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
225 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
226 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
227 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
228 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
231 int frescan_fna_contract_renegotiate_sync
232 (const frsh_resource_id_t resource_id,
233 const fna_vres_id_t vres,
234 const frsh_contract_t *new_contract)
236 ERROR("not implemented\n");
241 * frescan_fna_contract_renegotiate_async()
243 * The operation enqueues a renegotiate operation for an existing
244 * vres, and returns immediately. The renegotiate operation is
245 * performed asynchronously, as soon as it is practical; meanwhile the
246 * system operation will continue normally. When the renegotiation is
247 * made, if the on-line admission test is enabled it determines
248 * whether the contract can be admitted or not based on the current
249 * contracts established in the system. If it cannot be admitted, the
250 * old contract remains in effect. If it can be admitted, it
251 * recalculates all necessary parameters for the contracts already
252 * present in the system.
254 * When the operation is completed, notification is made to the
255 * caller, if requested, via a signal. The status of the operation (in
256 * progress, admitted, rejected) can be checked with the
257 * frsh_vres_get_renegotiation_status() operation. The argument
258 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
259 * signal value and in this case signal_info is to be sent with the signal.
261 * @param[in] resource_id The network we are referring to (a protocol
262 * could be able to handle several networks at the same time)
263 * @param[in] vres The internal virtual resource id to renegotiate
264 * @param[in] new_contract The new contract
265 * @param[in] signal_to_notify Signal number to use to notify vres of
266 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
267 * @param[in] signal_info: Associated info that will come with the signal.
268 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
271 * 0 if there are no errors \n
272 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
273 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
274 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
275 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
276 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
277 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
278 * NULL nor a valid POSIX signal \n
281 int frescan_fna_contract_renegotiate_async
282 (const frsh_resource_id_t resource_id,
283 const fna_vres_id_t vres,
284 const frsh_contract_t *new_contract,
285 frsh_signal_t signal_to_notify,
286 frsh_signal_info_t signal_info)
288 ERROR("not implemented\n");
293 * frescan_fna_vres_get_renegotiation_status()
295 * The operation reports on the status of the last renegotiation
296 * operation enqueued for the specified vres. It is callable even
297 * after notification of the completion of such operation, if
300 * If the vres is not and has not been involved in any of the
301 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
302 * operations, the status returned is FNA_NOT_REQUESTED
304 * @param[in] resource_id The network we are referring to (a protocol
305 * could be able to handle several networks at the same time)
306 * @param[in] vres The internal virtual resource id we want the status from
307 * @param[in] renegotiation_status The status of the last renegotiation on
308 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
309 * FRSH_RS_NOT_REQUESTED)
312 * 0 if there are no errors \n
313 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
314 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
315 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
316 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
317 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
320 int frescan_fna_vres_get_renegotiation_status
321 (const frsh_resource_id_t resource_id,
322 const fna_vres_id_t vres,
323 frsh_renegotiation_status_t *renegotiation_status)
325 ERROR("not implemented\n");
330 * frescan_fna_vres_destroy()
332 * The operation eliminates the specified vres
333 * and recalculates all necessary parameters for the contracts
334 * remaining in the system. This is a potentially blocking operation;
335 * it returns when the system has made the changes effective.
337 * @param[in] resource_id The network we are referring to (a protocol
338 * could be able to handle several networks at the same time)
339 * @param[in] vres The internal virtual resource id to destroy
342 * 0 if there are no errors \n
343 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
344 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
345 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
346 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
347 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
350 int frescan_fna_vres_destroy
351 (const frsh_resource_id_t resource_id,
352 const fna_vres_id_t vres)
354 ERROR("not implemented\n");
359 * frescan_fna_vres_get_contract()
361 * This operation stores the contract parameters currently associated
362 * with the specified vres in the variable pointed to by
363 * contract. It returns an error if the vres_id is not recognised.
365 * @param[in] resource_id The network we are referring to (a protocol
366 * could be able to handle several networks at the same time)
367 * @param[in] vres The internal virtual resource id
368 * @param[out] contract The contract parameters that we want
371 * 0 if there are no errors \n
372 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
373 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
374 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
375 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
376 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
379 int frescan_fna_vres_get_contract
380 (const frsh_resource_id_t resource_id,
381 const fna_vres_id_t vres,
382 frsh_contract_t *contract)
384 ERROR("not implemented\n");
389 * frescan_fna_vres_get_usage()
391 * This function gets the execution time spent by all messages that have been
392 * sent through the specified vres.
394 * @param[in] resource_id The network we are referring to (a protocol
395 * could be able to handle several networks at the same time)
396 * @param[in] vres The internal virtual resource id
397 * @param[out] usage Execution time spent by this vres
400 * 0 if there are no errors \n
401 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
402 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
403 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
404 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
405 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
408 int frescan_fna_vres_get_usage
409 (const frsh_resource_id_t resource_id,
410 const fna_vres_id_t vres,
411 struct timespec *usage)
413 ERROR("not implemented\n");
418 * frescan_fna_vres_get_remaining_budget()
420 * This function stores in the variable pointed to by budget the
421 * remaining execution-time budget associated with the specified
422 * vres in the present period.
424 * @param[in] resource_id The network we are referring to (a protocol
425 * could be able to handle several networks at the same time)
426 * @param[in] vres The internal virtual resource id
427 * @param[out] remaining_budget The remaining budget for this period
430 * 0 if there are no errors \n
431 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
432 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
433 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
434 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
435 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
438 int frescan_fna_vres_get_remaining_budget
439 (const frsh_resource_id_t resource_id,
440 const fna_vres_id_t vres,
441 struct timespec *remaining_budget)
443 ERROR("not implemented\n");
448 * frescan_fna_vres_get_budget_and_period()
450 * This function gets the budget and period associated with the specified vres
451 * for each period. If one of these pointers is NULL, the corresponding
452 * information is not stored.
454 * @param[in] resource_id The network we are referring to (a protocol
455 * could be able to handle several networks at the same time)
456 * @param[in] vres The internal virtual resource id
457 * @param[out] budget The budget associated to vres
458 * @param[out] period The period associated to vres
461 * 0 if there are no errors \n
462 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
463 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
464 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
465 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
466 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
469 int frescan_fna_vres_get_budget_and_period
470 (const frsh_resource_id_t resource_id,
471 const fna_vres_id_t vres,
472 struct timespec *budget,
473 struct timespec *period)
475 ERROR("not implemented\n");
481 ///////////////////////////////////////////////////////////////////
482 // SPARE CAPACITY FUNCIONS
483 ///////////////////////////////////////////////////////////////////
486 * @defgroup fnaspare FNA Spare Capacity
489 * The following functions are used to get spare capacity data
495 * frescan_fna_resource_get_capacity()
497 * This operation gets the spare capacity currently assigned to a importance
498 * level. If we divide this value by UINT32_MAX we will get the network
499 * utilization associated to the spare capacity of a importance level.
501 * The following is typically in stdint.h: \n
502 * - typedef unsigned int uint32_t; \n
503 * - # define UINT32_MAX (4294967295U) \n
505 * @param[in] resource_id The network we are referring to (a protocol
506 * could be able to handle several networks at the same time)
507 * @param[in] importance The importance we want the capacity of
508 * @param[out] capacity The spare capacity for that importance level
511 * 0 if there are no errors \n
512 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
513 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
514 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
515 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
518 int frescan_fna_resource_get_capacity
519 (const frsh_resource_id_t resource_id,
520 const int importance,
523 ERROR("not implemented\n");
528 * frescan_fna_resource_get_total_weight()
530 * This function gets the sum of the weight parameters for all vres in a
531 * network of an importance level.
533 * @param[in] resource_id The network we are referring to (a protocol
534 * could be able to handle several networks at the same time)
535 * @param[in] importance The importance we want the total weight of
536 * @param[out] total_weight The total weight for that importance level
539 * 0 if there are no errors \n
540 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
541 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
542 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
543 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
546 int frescan_fna_resource_get_total_weight
547 (const frsh_resource_id_t resource_id,
548 const int importance,
551 ERROR("not implemented\n");
556 * frescan_fna_vres_decrease_capacity()
558 * This function allows to ask for less budget and period than what we
559 * received. The request must be compatible with the rest of contract
560 * parameters of the vres. If we want to recover the released capacity
561 * we will need to renegotiate.
563 * @param[in] resource_id The network we are referring to (a protocol
564 * could be able to handle several networks at the same time)
565 * @param[in] vres The internal virtual resource id
566 * @param[in] new_budget The new_budget
567 * @param[in] new_period The new Period
570 * 0 if there are no errors \n
571 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
572 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
573 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
574 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
575 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
576 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
580 int frescan_fna_vres_decrease_capacity
581 (const frsh_resource_id_t resource_id,
582 const fna_vres_id_t vres,
583 const struct timespec new_budget,
584 const struct timespec new_period)
586 ERROR("not implemented\n");
590 ///////////////////////////////////////////////////////////////////
591 // SEND RECEIVE OPERATIONS
592 ///////////////////////////////////////////////////////////////////
595 * frescan_fna_send_sync()
597 * Similar to previous function but now the sending thread gets blocked
598 * until the message is already sent to the network.
600 * @param[in] endpoint The send endpoint we are sending through. It must
601 * be bound to a virtual resource (resource_id is in the endpoint).
602 * @param[in] msg The message we want to send
603 * @param[in] size The size in bytes of the message
606 * 0 if there are no errors \n
607 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
608 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
609 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
610 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
611 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
612 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
613 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
614 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
617 int frescan_fna_send_sync
618 (const fna_endpoint_data_t *endpoint,
622 ERROR("not implemented\n");
627 * frescan_fna_send_async()
629 * This operation sends a message stored in msg and of length size
630 * through the given send endpoint. The operation is non-blocking and
631 * returns immediately.
633 * @param[in] endpoint The send endpoint we are sending through. It must
634 * be bound to a virtual resource (resource_id is in the endpoint).
635 * @param[in] msg The message we want to send
636 * @param[in] size The size in bytes of the message
639 * 0 if there are no errors \n
640 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
641 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
642 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
643 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
644 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
645 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
646 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
647 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
650 int frescan_fna_send_async
651 (const fna_endpoint_data_t *endpoint,
656 frescan_send_params_t params;
658 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
659 "net:%u dest:%u chan:%u size:%u ss:%u\n",
660 endpoint->resource_id, endpoint->destination,
661 endpoint->stream_id, size, endpoint->vres);
663 params.net = (frescan_network_t)endpoint->resource_id;
664 params.to = (frescan_node_t)endpoint->destination;
665 params.channel = (frescan_channel_t)endpoint->stream_id;
666 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
667 params.ss = endpoint->vres;
669 ret = frescan_send(¶ms, (uint8_t *)msg, size);
671 ERROR ("could not send message\n");
679 * frescan_fna_receive_sync()
681 * This operation is used to receive messages from the network with a
682 * blocking behavior (if there are no messages this operation blocks
683 * the calling thread).
685 * When a message is available, it is copied to buffer (up to its size).
686 * The number of bytes copied is returned in received_bytes. The rest
687 * of the bytes of that message will be lost or not depending on the
688 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
690 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
691 * too small for the message received. In this case the message is
694 * Messages arriving at a receiver buffer that is full will be handled
695 * according to the queueing policy of the endpoint (overwrite oldest,
698 * @param[in] endpoint The receive endpoint we are receiving from.
699 * (resource_id is in the endpoint).
700 * @param[out] buffer Buffer for storing the received message
701 * @param[in] buffer_size The size in bytes of this buffer
702 * @param[out] received_bytes The actual number of received bytes
703 * @param[out] from Address of the sender node
706 * 0 if there are no errors \n
707 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
708 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
709 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
710 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
711 * FNA_ERR_NO_SPACE: if the message size is bigger than the
712 * provided buffer. \n
715 int frescan_fna_receive_sync
716 (const fna_endpoint_data_t *endpoint,
718 const size_t buffer_size,
719 size_t *received_bytes,
720 frsh_network_address_t *from)
723 frescan_recv_params_t params;
724 frescan_node_t frescan_from;
727 params.net = (frescan_network_t)endpoint->resource_id;
728 params.channel = (frescan_channel_t)endpoint->stream_id;
729 params.flags = FRESCAN_SYNC;
731 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
732 "net:%u chan:%u size:%u\n",
733 endpoint->resource_id, endpoint->stream_id, buffer_size);
735 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
736 received_bytes, &frescan_from, &prio);
739 ERROR ("error while receiving message");
743 *from = (frsh_network_address_t)frescan_from;
745 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
746 "msg received, from:%u bytes:%u prio:%u\n",
747 *from, *received_bytes, prio);
753 * frescan_fna_receive_async()
755 * This operation is similar to the previous one but it works in a non
756 * blocking (asynchronous) fashion. If no message is available it
757 * returns with error FNA_NO_MESSAGE.
759 * @param[in] endpoint The receive endpoint we are receiving from.
760 * (resource_id is in the endpoint).
761 * @param[out] buffer Buffer for storing the received message
762 * @param[in] buffer_size The size in bytes of this buffer
763 * @param[out] received_bytes The actual number of received bytes
764 * @param[out] from Address of the sender node
767 * 0 if there are no errors \n
768 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
769 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
770 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
771 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
772 * FNA_ERR_NO_SPACE: if the message size is bigger than the
773 * provided buffer. \n
774 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
777 int frescan_fna_receive_async
778 (const fna_endpoint_data_t *endpoint,
780 const size_t buffer_size,
781 size_t *received_bytes,
782 frsh_network_address_t *from)
784 ERROR("not implemented\n");
789 * frescan_fna_send_endpoint_get_status()
791 * This function tells the number of messages still pending in the
792 * endpoint queue, whether the network is up or down with some
793 * optional information which is protocol_dependent.
795 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
796 * @param[out] number_of_pending_messages The number of pending messages
797 * @param[out] network_status How is the network (up, down..)
798 * @param[out] protocol_status Protocol dependent status info
801 * 0 if there are no errors \n
802 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
803 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
804 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
805 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
808 int frescan_fna_send_endpoint_get_status
809 (const fna_endpoint_data_t *endpoint,
810 int *number_of_pending_messages,
811 frsh_endpoint_network_status_t *network_status,
812 frsh_protocol_status_t *protocol_status)
814 ERROR("not implemented\n");
819 * frescan_fna_receive_endpoint_created()
821 * This operation is a called from frsh_receive_endpoint_create with a
822 * receive_endpoint structure already filled.
824 * Receiving endpoints are not bound to any network vres, this is
825 * because don't originate any traffic.
827 * @param[in] endpoint the endpoint object.
830 * 0 if there are no errors \n
831 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
832 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
833 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
834 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
836 int frescan_fna_receive_endpoint_created
837 (fna_endpoint_data_t *endpoint)
839 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
844 * frescan_fna_receive_endpoint_get_pending_messages
846 * This function tells the number of messages still pending in the
847 * endpoint queue, whether the network is up or down and some optional
848 * information which is protocol dependent.
850 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
851 * @param[out] number_of_pending_messages The number of pending messages
852 * @param[out] network_status How is the network (up, down..)
853 * @param[out] protocol_status Protocol dependent status info
856 * 0 if there are no errors \n
857 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
858 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
859 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
860 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
863 int frescan_fna_receive_endpoint_get_status
864 (const fna_endpoint_data_t *endpoint,
865 int *number_of_pending_messages,
866 frsh_endpoint_network_status_t *network_status,
867 frsh_protocol_status_t *protocol_status)
869 ERROR("not implemented\n");
873 //////////////////////////////////////////////////////////////////////
874 // NETWORK CONFIGURATION FUNCTIONS
875 //////////////////////////////////////////////////////////////////////
878 * frescan_fna_network_get_max_message_size()
880 * This operation gives the maximum number of bytes that can be sent
881 * at a time through the send function when using the network designated by
882 * 'resource_id' and sending it to 'destination'.
884 * If the application needs to send bigger messages it will have to
887 * Some protocols, like IP, are capable of sending large messages
888 * (and use fragmentation internally) but other protocols don't.
890 * @param[in] resource_id The network we want the tx time from.
891 * @param[in] destination The destination address
892 * @param[out] max_size The maximum number of bytes for each message
895 * 0 if there are no errors \n
896 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
897 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
898 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
899 * a network accessible from the current processing node \n
900 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
904 int frescan_fna_network_get_max_message_size
905 (const frsh_resource_id_t resource_id,
906 const frsh_network_address_t destination,
909 ERROR("not implemented\n");
914 * frescan_fna_network_bytes_to_budget()
916 * This operation converts a number of bytes into a temporal budget for
917 * a specific network. Network overheads are not included here but are
918 * considered internally when negotiating a specific contract.
920 * @param[in] resource_id The network
921 * @param[in] nbytes Number of bytes
922 * @param[out] budget The network budget for nbytes
925 * 0 if there are no errors \n
926 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
927 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
928 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
929 * a network accessible from the current processing node \n
930 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
934 int frescan_fna_network_bytes_to_budget
935 (const frsh_resource_id_t resource_id,
937 struct timespec *budget)
939 int number_of_packets;
941 if (budget == NULL || nbytes < 0) {
945 // we measure the budget in number of FRESCAN frames (8 bytes)
946 number_of_packets = (int) ceil((double)nbytes / 8.0);
948 // we store the budget in number of packets instead of in time. We
949 // use a field in the timespec structure.
950 budget->tv_sec = number_of_packets;
952 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
953 "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
959 * frescan_fna_network_budget_to_bytes()
961 * This operation converts a temporal budget into a number of bytes for
962 * a specific network. Network overheads are not included.
964 * @param[in] resource_id The network
965 * @param[in] budget The network budget for nbytes
966 * @param[out] nbytes Number of bytes
969 * 0 if there are no errors \n
970 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
971 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
972 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
973 * a network accessible from the current processing node \n
974 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
975 * an invalid time value \n
978 int frescan_fna_network_budget_to_bytes
979 (const frsh_resource_id_t resource_id,
980 const struct timespec *budget,
983 int number_of_packets;
985 if (budget == NULL || nbytes == NULL) {
989 number_of_packets = budget->tv_sec;
991 *nbytes = number_of_packets * 8;
997 * frescan_fna_network_get_min_eff_budget()
999 * This operation gets the minimum effective budget for a network. Each message
1000 * consumes a contracted budget in "chunks" (i.e: packets) that we call
1001 * minimum effective budget.
1003 * A negotiated contract, for N bytes in a period T, means that there is a
1004 * virtual resource that reserves for the user:
1006 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1008 * Note that if the user decides not to send these N bytes at once but, say,
1009 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1010 * budget will become exhausted before sending all the bytes.
1012 * @param[in] resource_id The network
1013 * @param[out] budget The network budget
1016 * 0 if there are no errors \n
1017 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1018 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1019 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1020 * a network accessible from the current processing node \n
1021 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1024 int frescan_fna_network_get_min_eff_budget
1025 (const frsh_resource_id_t resource_id,
1026 struct timespec *budget)
1028 if (budget == NULL) {
1037 // GLOBAL variable to install the network protocol in FRESCOR
1039 fna_operations_t frescan_fna_operations = {
1040 .fna_init = frescan_fna_init,
1041 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1042 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1043 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1044 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1045 .fna_vres_destroy = frescan_fna_vres_destroy,
1046 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1047 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1048 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1049 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1050 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1051 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1052 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1053 .fna_send_sync = frescan_fna_send_sync,
1054 .fna_send_async = frescan_fna_send_async,
1055 .fna_receive_sync = frescan_fna_receive_sync,
1056 .fna_receive_async = frescan_fna_receive_async,
1057 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1058 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1059 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1060 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1061 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1062 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1063 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget