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_bwres.h" /* frescan_bwres_init, ... */
71 #include "frescan_types.h"
72 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
73 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
75 //////////////////////////////////////////////////////////////////////
77 //////////////////////////////////////////////////////////////////////
82 * This function will be hooked to the frsh_init function and it is
83 * intented to initialize the protocol and its structures.
85 * @param[in] resource_id The network we are referring to (a protocol
86 * could be able to handle several networks at the same time)
89 * 0 if there are no errors \n
90 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
91 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
92 * FNA_ERR_ALREADY_INITIALIZED:
93 * if the function has already been called before (with success) \n
96 int frescan_fna_init(const frsh_resource_id_t resource_id)
99 frescan_init_params_t init_params;
101 // TODO: resource_id must be relative or sth
102 // TODO: init_params must be configurable
103 init_params.net = (frescan_network_t)resource_id;
104 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
105 init_params.tx_fp_max_prio = 10;
106 init_params.rx_num_of_channels = 10;
107 init_params.rx_channel_max_prio = NULL;
109 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
110 "Initializing FRESCAN FNA node%u\n", FRSH_CPU_ID_DEFAULT);
112 ret = frescan_init(&init_params);
113 if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
115 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
117 ret = frescan_bwres_init(init_params.net);
118 if (ret != 0) FRESCAN_ERROR ("could not init BWRES");
123 ///////////////////////////////////////////////////////////////////
125 ///////////////////////////////////////////////////////////////////
127 int frescan_fna_group_change_mode_sync
128 (const frsh_resource_id_t resource_id,
129 const frsh_contracts_group_t *contracts_to_neg,
130 const frsh_contracts_group_t *contracts_to_reneg,
131 const fna_vres_group_t *vres_to_reneg,
132 const fna_vres_group_t *vres_to_cancel,
133 fna_vres_group_t *new_vres)
137 frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
139 // convert fna_vres to ss
140 if (vres_to_reneg == NULL) {
141 ss_to_reneg.size = 0;
143 ss_to_reneg.size = vres_to_reneg->size;
144 if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
145 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
149 for(i=0; i<ss_to_reneg.size; i++) {
151 (frescan_ss_t)vres_to_reneg->vres[i];
155 if (vres_to_cancel == NULL) {
156 ss_to_cancel.size = 0;
158 ss_to_cancel.size = vres_to_cancel->size;
159 if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
160 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
164 for(i=0; i<ss_to_cancel.size; i++) {
166 (frescan_ss_t)vres_to_cancel->vres[i];
170 if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
171 FRESCAN_ERROR("new_vres is NULL\n");
176 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
177 "calling frescan_bwres_group_change_mode_sync\n");
179 ret = frescan_bwres_group_change_mode_sync
180 ((frescan_network_t)resource_id,
187 if (ret != 0) return -1;
189 if (accepted == false) {
190 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
191 return -1; // TODO: change to constant FNA_REJECTED
194 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
196 // convert new ss to fna_vres
197 if (contracts_to_neg != NULL) {
198 new_vres->size = ss_new.size;
199 for(i=0; i<new_vres->size; i++) {
200 new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
208 * frescan_fna_contract_negotiate()
210 * The operation negotiates a contract and if accepted it will return
211 * a fna_vres_id_t. It will also check that the given contract_id is unique
212 * within the network.
214 * If the on-line admission test is enabled, it determines whether the
215 * contract can be admitted or not based on the current contracts
216 * established in the network. Then it creates the vres and
217 * recalculates all necessary parameters for the contracts already
218 * present in the system.
220 * This is a potentially blocking operation, it returns when the
221 * system has either rejected the contract, or admitted it and made it
224 * @param[in] resource_id The network we are referring to (a protocol
225 * could be able to handle several networks at the same time)
226 * @param[in] contract The contract parameters to negotiate
227 * @param[out] vres The internal virtual resource id
230 * 0 if there are no errors (in this case it also means contract accepted) \n
231 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
232 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
233 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
234 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
235 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
236 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
237 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
240 int frescan_fna_contract_negotiate
241 (const frsh_resource_id_t resource_id,
242 const frsh_contract_t *contract,
246 frsh_contracts_group_t contracts_to_neg;
247 fna_vres_group_t new_vres;
249 contracts_to_neg.size = 1;
250 contracts_to_neg.contracts[0] = *contract;
252 ret = frescan_fna_group_change_mode_sync
253 (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
254 if (ret != 0) return ret;
256 *vres = new_vres.vres[0];
261 * frescan_fna_contract_renegotiate_sync()
263 * The operation renegotiates a contract for an existing vres. If
264 * the on-line admission test is enabled it determines whether the
265 * contract can be admitted or not based on the current contracts
266 * established in the system. If it cannot be admitted, the old
267 * contract remains in effect and an error is returned. If it can be
268 * admitted, it recalculates all necessary parameters for the
269 * contracts already present in the system and returns zero. This is a
270 * potentially blocking operation; it returns when the system has
271 * either rejected the new contract, or admitted it and made it
274 * @param[in] resource_id The network we are referring to (a protocol
275 * could be able to handle several networks at the same time)
276 * @param[in] vres The internal virtual resource id to renegotiate
277 * @param[in] new_contract The new contract
280 * 0 if there are no errors (in this case it also means contract accepted) \n
281 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
282 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
283 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
284 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
285 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
286 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
287 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
290 int frescan_fna_contract_renegotiate_sync
291 (const frsh_resource_id_t resource_id,
292 const fna_vres_id_t vres,
293 const frsh_contract_t *new_contract)
295 frsh_contracts_group_t contracts_to_reneg;
296 fna_vres_group_t vres_to_reneg;
298 contracts_to_reneg.size = 1;
299 contracts_to_reneg.contracts[0] = *new_contract;
300 vres_to_reneg.size = 1;
301 vres_to_reneg.vres[0] = vres;
303 return frescan_fna_group_change_mode_sync
304 (resource_id, NULL, &contracts_to_reneg,
305 &vres_to_reneg, NULL, NULL);
309 * frescan_fna_contract_renegotiate_async()
311 * The operation enqueues a renegotiate operation for an existing
312 * vres, and returns immediately. The renegotiate operation is
313 * performed asynchronously, as soon as it is practical; meanwhile the
314 * system operation will continue normally. When the renegotiation is
315 * made, if the on-line admission test is enabled it determines
316 * whether the contract can be admitted or not based on the current
317 * contracts established in the system. If it cannot be admitted, the
318 * old contract remains in effect. If it can be admitted, it
319 * recalculates all necessary parameters for the contracts already
320 * present in the system.
322 * When the operation is completed, notification is made to the
323 * caller, if requested, via a signal. The status of the operation (in
324 * progress, admitted, rejected) can be checked with the
325 * frsh_vres_get_renegotiation_status() operation. The argument
326 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
327 * signal value and in this case signal_info is to be sent with the signal.
329 * @param[in] resource_id The network we are referring to (a protocol
330 * could be able to handle several networks at the same time)
331 * @param[in] vres The internal virtual resource id to renegotiate
332 * @param[in] new_contract The new contract
333 * @param[in] signal_to_notify Signal number to use to notify vres of
334 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
335 * @param[in] signal_info: Associated info that will come with the signal.
336 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
339 * 0 if there are no errors \n
340 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
341 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
342 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
343 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
344 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
345 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
346 * NULL nor a valid POSIX signal \n
349 int frescan_fna_contract_renegotiate_async
350 (const frsh_resource_id_t resource_id,
351 const fna_vres_id_t vres,
352 const frsh_contract_t *new_contract,
353 frsh_signal_t signal_to_notify,
354 frsh_signal_info_t signal_info)
356 FRESCAN_ERROR("not implemented\n");
361 * frescan_fna_vres_get_renegotiation_status()
363 * The operation reports on the status of the last renegotiation
364 * operation enqueued for the specified vres. It is callable even
365 * after notification of the completion of such operation, if
368 * If the vres is not and has not been involved in any of the
369 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
370 * operations, the status returned is FNA_NOT_REQUESTED
372 * @param[in] resource_id The network we are referring to (a protocol
373 * could be able to handle several networks at the same time)
374 * @param[in] vres The internal virtual resource id we want the status from
375 * @param[in] renegotiation_status The status of the last renegotiation on
376 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
377 * FRSH_RS_NOT_REQUESTED)
380 * 0 if there are no errors \n
381 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
382 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
383 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
384 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
385 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
388 int frescan_fna_vres_get_renegotiation_status
389 (const frsh_resource_id_t resource_id,
390 const fna_vres_id_t vres,
391 frsh_renegotiation_status_t *renegotiation_status)
393 FRESCAN_ERROR("not implemented\n");
398 * frescan_fna_vres_destroy()
400 * The operation eliminates the specified vres
401 * and recalculates all necessary parameters for the contracts
402 * remaining in the system. This is a potentially blocking operation;
403 * it returns when the system has made the changes effective.
405 * @param[in] resource_id The network we are referring to (a protocol
406 * could be able to handle several networks at the same time)
407 * @param[in] vres The internal virtual resource id to destroy
410 * 0 if there are no errors \n
411 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
412 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
413 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
414 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
415 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
418 int frescan_fna_vres_destroy
419 (const frsh_resource_id_t resource_id,
420 const fna_vres_id_t vres)
422 fna_vres_group_t vres_to_cancel;
424 vres_to_cancel.size = 1;
425 vres_to_cancel.vres[0] = vres;
427 return frescan_fna_group_change_mode_sync
428 (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
432 * frescan_fna_vres_get_contract()
434 * This operation stores the contract parameters currently associated
435 * with the specified vres in the variable pointed to by
436 * contract. It returns an error if the vres_id is not recognised.
438 * @param[in] resource_id The network we are referring to (a protocol
439 * could be able to handle several networks at the same time)
440 * @param[in] vres The internal virtual resource id
441 * @param[out] contract The contract parameters that we want
444 * 0 if there are no errors \n
445 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
446 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
447 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
448 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
449 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
452 int frescan_fna_vres_get_contract
453 (const frsh_resource_id_t resource_id,
454 const fna_vres_id_t vres,
455 frsh_contract_t *contract)
457 FRESCAN_ERROR("not implemented\n");
462 * frescan_fna_vres_get_usage()
464 * This function gets the execution time spent by all messages that have been
465 * sent through the specified vres.
467 * @param[in] resource_id The network we are referring to (a protocol
468 * could be able to handle several networks at the same time)
469 * @param[in] vres The internal virtual resource id
470 * @param[out] usage Execution time spent by this vres
473 * 0 if there are no errors \n
474 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
475 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
476 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
477 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
478 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
481 int frescan_fna_vres_get_usage
482 (const frsh_resource_id_t resource_id,
483 const fna_vres_id_t vres,
484 struct timespec *usage)
486 FRESCAN_ERROR("not implemented\n");
491 * frescan_fna_vres_get_remaining_budget()
493 * This function stores in the variable pointed to by budget the
494 * remaining execution-time budget associated with the specified
495 * vres in the present period.
497 * @param[in] resource_id The network we are referring to (a protocol
498 * could be able to handle several networks at the same time)
499 * @param[in] vres The internal virtual resource id
500 * @param[out] remaining_budget The remaining budget for this period
503 * 0 if there are no errors \n
504 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
505 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
506 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
507 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
508 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
511 int frescan_fna_vres_get_remaining_budget
512 (const frsh_resource_id_t resource_id,
513 const fna_vres_id_t vres,
514 struct timespec *remaining_budget)
516 FRESCAN_ERROR("not implemented\n");
521 * frescan_fna_vres_get_budget_and_period()
523 * This function gets the budget and period associated with the specified vres
524 * for each period. If one of these pointers is NULL, the corresponding
525 * information is not stored.
527 * @param[in] resource_id The network we are referring to (a protocol
528 * could be able to handle several networks at the same time)
529 * @param[in] vres The internal virtual resource id
530 * @param[out] budget The budget associated to vres
531 * @param[out] period The period associated to vres
534 * 0 if there are no errors \n
535 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
536 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
537 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
538 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
539 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
542 int frescan_fna_vres_get_budget_and_period
543 (const frsh_resource_id_t resource_id,
544 const fna_vres_id_t vres,
545 struct timespec *budget,
546 struct timespec *period)
548 FRESCAN_ERROR("not implemented\n");
554 ///////////////////////////////////////////////////////////////////
555 // SPARE CAPACITY FUNCIONS
556 ///////////////////////////////////////////////////////////////////
559 * @defgroup fnaspare FNA Spare Capacity
562 * The following functions are used to get spare capacity data
568 * frescan_fna_resource_get_capacity()
570 * This operation gets the spare capacity currently assigned to a importance
571 * level. If we divide this value by UINT32_MAX we will get the network
572 * utilization associated to the spare capacity of a importance level.
574 * The following is typically in stdint.h: \n
575 * - typedef unsigned int uint32_t; \n
576 * - # define UINT32_MAX (4294967295U) \n
578 * @param[in] resource_id The network we are referring to (a protocol
579 * could be able to handle several networks at the same time)
580 * @param[in] importance The importance we want the capacity of
581 * @param[out] capacity The spare capacity for that importance level
584 * 0 if there are no errors \n
585 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
586 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
587 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
588 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
591 int frescan_fna_resource_get_capacity
592 (const frsh_resource_id_t resource_id,
593 const int importance,
596 FRESCAN_ERROR("not implemented\n");
601 * frescan_fna_resource_get_total_weight()
603 * This function gets the sum of the weight parameters for all vres in a
604 * network of an importance level.
606 * @param[in] resource_id The network we are referring to (a protocol
607 * could be able to handle several networks at the same time)
608 * @param[in] importance The importance we want the total weight of
609 * @param[out] total_weight The total weight for that importance level
612 * 0 if there are no errors \n
613 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
614 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
615 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
616 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
619 int frescan_fna_resource_get_total_weight
620 (const frsh_resource_id_t resource_id,
621 const int importance,
624 FRESCAN_ERROR("not implemented\n");
629 * frescan_fna_vres_decrease_capacity()
631 * This function allows to ask for less budget and period than what we
632 * received. The request must be compatible with the rest of contract
633 * parameters of the vres. If we want to recover the released capacity
634 * we will need to renegotiate.
636 * @param[in] resource_id The network we are referring to (a protocol
637 * could be able to handle several networks at the same time)
638 * @param[in] vres The internal virtual resource id
639 * @param[in] new_budget The new_budget
640 * @param[in] new_period The new Period
643 * 0 if there are no errors \n
644 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
645 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
646 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
647 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
648 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
649 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
653 int frescan_fna_vres_decrease_capacity
654 (const frsh_resource_id_t resource_id,
655 const fna_vres_id_t vres,
656 const struct timespec new_budget,
657 const struct timespec new_period)
659 FRESCAN_ERROR("not implemented\n");
663 ///////////////////////////////////////////////////////////////////
664 // SEND RECEIVE OPERATIONS
665 ///////////////////////////////////////////////////////////////////
668 * frescan_fna_send_sync()
670 * Similar to previous function but now the sending thread gets blocked
671 * until the message is already sent to the network.
673 * @param[in] endpoint The send endpoint we are sending through. It must
674 * be bound to a virtual resource (resource_id is in the endpoint).
675 * @param[in] msg The message we want to send
676 * @param[in] size The size in bytes of the message
679 * 0 if there are no errors \n
680 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
681 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
682 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
683 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
684 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
685 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
686 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
687 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
690 int frescan_fna_send_sync
691 (const fna_endpoint_data_t *endpoint,
695 FRESCAN_ERROR("not implemented\n");
700 * frescan_fna_send_async()
702 * This operation sends a message stored in msg and of length size
703 * through the given send endpoint. The operation is non-blocking and
704 * returns immediately.
706 * @param[in] endpoint The send endpoint we are sending through. It must
707 * be bound to a virtual resource (resource_id is in the endpoint).
708 * @param[in] msg The message we want to send
709 * @param[in] size The size in bytes of the message
712 * 0 if there are no errors \n
713 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
714 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
715 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
716 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
717 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
718 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
719 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
720 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
723 int frescan_fna_send_async
724 (const fna_endpoint_data_t *endpoint,
729 frescan_send_params_t params;
731 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
732 "net:%u dest:%u chan:%u size:%u ss:%u\n",
733 endpoint->resource_id, endpoint->destination,
734 endpoint->stream_id, size, endpoint->vres);
736 params.net = (frescan_network_t)endpoint->resource_id;
737 params.to = (frescan_node_t)endpoint->destination;
738 params.channel = (frescan_channel_t)endpoint->stream_id;
739 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
740 params.ss = endpoint->vres;
742 ret = frescan_send(¶ms, (uint8_t *)msg, size);
744 FRESCAN_ERROR ("could not send message\n");
752 * frescan_fna_receive_sync()
754 * This operation is used to receive messages from the network with a
755 * blocking behavior (if there are no messages this operation blocks
756 * the calling thread).
758 * When a message is available, it is copied to buffer (up to its size).
759 * The number of bytes copied is returned in received_bytes. The rest
760 * of the bytes of that message will be lost or not depending on the
761 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
763 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
764 * too small for the message received. In this case the message is
767 * Messages arriving at a receiver buffer that is full will be handled
768 * according to the queueing policy of the endpoint (overwrite oldest,
771 * @param[in] endpoint The receive endpoint we are receiving from.
772 * (resource_id is in the endpoint).
773 * @param[out] buffer Buffer for storing the received message
774 * @param[in] buffer_size The size in bytes of this buffer
775 * @param[out] received_bytes The actual number of received bytes
776 * @param[out] from Address of the sender node
779 * 0 if there are no errors \n
780 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
781 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
782 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
783 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
784 * FNA_ERR_NO_SPACE: if the message size is bigger than the
785 * provided buffer. \n
788 int frescan_fna_receive_sync
789 (const fna_endpoint_data_t *endpoint,
791 const size_t buffer_size,
792 size_t *received_bytes,
793 frsh_network_address_t *from)
796 frescan_recv_params_t params;
797 frescan_node_t frescan_from;
800 params.net = (frescan_network_t)endpoint->resource_id;
801 params.channel = (frescan_channel_t)endpoint->stream_id;
802 params.flags = FRESCAN_SYNC;
804 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
805 "net:%u chan:%u size:%u\n",
806 endpoint->resource_id, endpoint->stream_id, buffer_size);
808 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
809 received_bytes, &frescan_from, &prio);
812 FRESCAN_ERROR ("error while receiving message");
816 *from = (frsh_network_address_t)frescan_from;
818 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
819 "msg received, from:%u bytes:%u prio:%u\n",
820 *from, *received_bytes, prio);
826 * frescan_fna_receive_async()
828 * This operation is similar to the previous one but it works in a non
829 * blocking (asynchronous) fashion. If no message is available it
830 * returns with error FNA_NO_MESSAGE.
832 * @param[in] endpoint The receive endpoint we are receiving from.
833 * (resource_id is in the endpoint).
834 * @param[out] buffer Buffer for storing the received message
835 * @param[in] buffer_size The size in bytes of this buffer
836 * @param[out] received_bytes The actual number of received bytes
837 * @param[out] from Address of the sender node
840 * 0 if there are no errors \n
841 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
842 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
843 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
844 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
845 * FNA_ERR_NO_SPACE: if the message size is bigger than the
846 * provided buffer. \n
847 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
850 int frescan_fna_receive_async
851 (const fna_endpoint_data_t *endpoint,
853 const size_t buffer_size,
854 size_t *received_bytes,
855 frsh_network_address_t *from)
857 FRESCAN_ERROR("not implemented\n");
862 * frescan_fna_send_endpoint_get_status()
864 * This function tells the number of messages still pending in the
865 * endpoint queue, whether the network is up or down with some
866 * optional information which is protocol_dependent.
868 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
869 * @param[out] number_of_pending_messages The number of pending messages
870 * @param[out] network_status How is the network (up, down..)
871 * @param[out] protocol_status Protocol dependent status info
874 * 0 if there are no errors \n
875 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
876 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
877 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
878 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
881 int frescan_fna_send_endpoint_get_status
882 (const fna_endpoint_data_t *endpoint,
883 int *number_of_pending_messages,
884 frsh_endpoint_network_status_t *network_status,
885 frsh_protocol_status_t *protocol_status)
887 FRESCAN_ERROR("not implemented\n");
892 * frescan_fna_receive_endpoint_created()
894 * This operation is a called from frsh_receive_endpoint_create with a
895 * receive_endpoint structure already filled.
897 * Receiving endpoints are not bound to any network vres, this is
898 * because don't originate any traffic.
900 * @param[in] endpoint the endpoint object.
903 * 0 if there are no errors \n
904 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
905 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
906 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
907 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
909 int frescan_fna_receive_endpoint_created
910 (fna_endpoint_data_t *endpoint)
912 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
917 * frescan_fna_receive_endpoint_get_pending_messages
919 * This function tells the number of messages still pending in the
920 * endpoint queue, whether the network is up or down and some optional
921 * information which is protocol dependent.
923 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
924 * @param[out] number_of_pending_messages The number of pending messages
925 * @param[out] network_status How is the network (up, down..)
926 * @param[out] protocol_status Protocol dependent status info
929 * 0 if there are no errors \n
930 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
931 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
932 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
933 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
936 int frescan_fna_receive_endpoint_get_status
937 (const fna_endpoint_data_t *endpoint,
938 int *number_of_pending_messages,
939 frsh_endpoint_network_status_t *network_status,
940 frsh_protocol_status_t *protocol_status)
942 FRESCAN_ERROR("not implemented\n");
946 //////////////////////////////////////////////////////////////////////
947 // NETWORK CONFIGURATION FUNCTIONS
948 //////////////////////////////////////////////////////////////////////
951 * frescan_fna_network_get_max_message_size()
953 * This operation gives the maximum number of bytes that can be sent
954 * at a time through the send function when using the network designated by
955 * 'resource_id' and sending it to 'destination'.
957 * If the application needs to send bigger messages it will have to
960 * Some protocols, like IP, are capable of sending large messages
961 * (and use fragmentation internally) but other protocols don't.
963 * @param[in] resource_id The network we want the tx time from.
964 * @param[in] destination The destination address
965 * @param[out] max_size The maximum number of bytes for each message
968 * 0 if there are no errors \n
969 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
970 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
971 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
972 * a network accessible from the current processing node \n
973 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
977 int frescan_fna_network_get_max_message_size
978 (const frsh_resource_id_t resource_id,
979 const frsh_network_address_t destination,
982 FRESCAN_ERROR("not implemented\n");
987 * frescan_fna_network_bytes_to_budget()
989 * This operation converts a number of bytes into a temporal budget for
990 * a specific network. Network overheads are not included here but are
991 * considered internally when negotiating a specific contract.
993 * @param[in] resource_id The network
994 * @param[in] nbytes Number of bytes
995 * @param[out] budget The network budget for nbytes
998 * 0 if there are no errors \n
999 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1000 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1001 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1002 * a network accessible from the current processing node \n
1003 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
1007 int frescan_fna_network_bytes_to_budget
1008 (const frsh_resource_id_t resource_id,
1009 const size_t nbytes,
1010 frsh_rel_time_t *budget)
1012 int number_of_packets;
1014 if (budget == NULL || nbytes < 0) {
1018 // number of FRESCAN frames (8 bytes)
1019 number_of_packets = (int) ceil((double)nbytes / 8.0);
1020 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
1023 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
1024 "bytes: %d -> budget: %ld us\n",
1025 nbytes, frsh_rel_time_to_usec(*budget));
1031 * frescan_fna_network_budget_to_bytes()
1033 * This operation converts a temporal budget into a number of bytes for
1034 * a specific network. Network overheads are not included.
1036 * @param[in] resource_id The network
1037 * @param[in] budget The network budget for nbytes
1038 * @param[out] nbytes Number of bytes
1041 * 0 if there are no errors \n
1042 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1043 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1044 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1045 * a network accessible from the current processing node \n
1046 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
1047 * an invalid time value \n
1050 int frescan_fna_network_budget_to_bytes
1051 (const frsh_resource_id_t resource_id,
1052 const frsh_rel_time_t *budget,
1055 int number_of_packets;
1057 if (budget == NULL || nbytes == NULL) {
1061 number_of_packets = frsh_rel_time_to_usec(*budget) /
1062 FRESCAN_FRAME_TX_TIME_US;
1064 *nbytes = number_of_packets * 8;
1070 * frescan_fna_network_get_min_eff_budget()
1072 * This operation gets the minimum effective budget for a network. Each message
1073 * consumes a contracted budget in "chunks" (i.e: packets) that we call
1074 * minimum effective budget.
1076 * A negotiated contract, for N bytes in a period T, means that there is a
1077 * virtual resource that reserves for the user:
1079 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1081 * Note that if the user decides not to send these N bytes at once but, say,
1082 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1083 * budget will become exhausted before sending all the bytes.
1085 * @param[in] resource_id The network
1086 * @param[out] budget The network budget
1089 * 0 if there are no errors \n
1090 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1091 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1092 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1093 * a network accessible from the current processing node \n
1094 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1097 int frescan_fna_network_get_min_eff_budget
1098 (const frsh_resource_id_t resource_id,
1099 struct timespec *budget)
1101 if (budget == NULL) {
1105 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1110 // GLOBAL variable to install the network protocol in FRESCOR
1112 fna_operations_t frescan_fna_operations = {
1113 .fna_init = frescan_fna_init,
1114 .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
1115 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1116 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1117 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1118 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1119 .fna_vres_destroy = frescan_fna_vres_destroy,
1120 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1121 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1122 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1123 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1124 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1125 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1126 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1127 .fna_send_sync = frescan_fna_send_sync,
1128 .fna_send_async = frescan_fna_send_async,
1129 .fna_receive_sync = frescan_fna_receive_sync,
1130 .fna_receive_async = frescan_fna_receive_async,
1131 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1132 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1133 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1134 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1135 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1136 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1137 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget