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 - 2009 by the FRESCOR consortium:
19 // Universidad de Cantabria, SPAIN
20 // University of York, UK
21 // Scuola Superiore Sant'Anna, ITALY
22 // Kaiserslautern University, GERMANY
23 // Univ. Politecnica 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
33 // The 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
39 // based on previous work (FSF) done in the FIRST project
41 // Copyright (C) 2005 Mälardalen University, SWEDEN
42 // Scuola Superiore S.Anna, ITALY
43 // Universidad de Cantabria, SPAIN
44 // University of York, UK
46 // This file is part of FNA (Frescor Network Adaptation)
48 // FNA is free software; you can redistribute it and/or modify it
49 // under terms of the GNU General Public License as published by the
50 // Free Software Foundation; either version 2, or (at your option) any
51 // later version. FNA is distributed in the hope that it will be
52 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
53 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54 // General Public License for more details. You should have received a
55 // copy of the GNU General Public License along with FNA; see file
56 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
57 // Cambridge, MA 02139, USA.
59 // As a special exception, including FNA header files in a file,
60 // instantiating FNA generics or templates, or linking other files
61 // with FNA objects to produce an executable application, does not
62 // by itself cause the resulting executable application to be covered
63 // by the GNU General Public License. This exception does not
64 // however invalidate any other reasons why the executable file might be
65 // covered by the GNU Public License.
66 // -----------------------------------------------------------------------
70 #include <math.h> /* ceil */
72 #include "frsh.h" /* frsh_resource_id_t, .. */
73 #include "frescan.h" /* frescan_init, ... */
74 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
75 #include "frescan_types.h"
76 #include "frescan_config.h"
77 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
78 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
79 #include "frescan_servers.h"
81 //////////////////////////////////////////////////////////////////////
83 //////////////////////////////////////////////////////////////////////
88 * This function will be hooked to the frsh_init function and it is
89 * intented to initialize the protocol and its structures.
91 * @param[in] resource_id The network we are referring to (a protocol
92 * could be able to handle several networks at the same time)
95 * 0 if there are no errors \n
96 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
97 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
98 * FNA_ERR_ALREADY_INITIALIZED:
99 * if the function has already been called before (with success) \n
102 int frescan_fna_init(const frsh_resource_id_t resource_id)
105 frescan_init_params_t init_params;
107 init_params.net = resource_id - FRESCAN_BWRES_FNA_NET_BASE;
108 init_params.node = FRESCAN_BWRES_FNA_LOCAL_NODE;
109 init_params.tx_fp_max_prio = FRESCAN_BWRES_TX_FP_MX_PRIO;
110 init_params.rx_num_of_channels = FRESCAN_BWRES_RX_NUM_CHANNELS;
111 init_params.rx_channel_max_prio = FRESCAN_BWRES_RX_CHAN_MX_PRIO;
113 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
114 "Initializing FRESCAN FNA node%u\n", init_params.node);
116 ret = frescan_init(&init_params);
118 FRESCAN_ERROR ("could not init FRESCAN\n");
122 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
124 ret = frescan_bwres_init(init_params.net);
126 FRESCAN_ERROR ("could not init BWRES\n");
133 ///////////////////////////////////////////////////////////////////
135 ///////////////////////////////////////////////////////////////////
137 int frescan_fna_group_change_mode_sync
138 (const frsh_resource_id_t resource_id,
139 const frsh_contracts_group_t *contracts_to_neg,
140 const frsh_contracts_group_t *contracts_to_reneg,
141 const fna_vres_group_t *vres_to_reneg,
142 const fna_vres_group_t *vres_to_cancel,
143 fna_vres_group_t *new_vres)
147 frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
149 // convert fna_vres to ss
150 if (vres_to_reneg == NULL) {
151 ss_to_reneg.size = 0;
153 ss_to_reneg.size = vres_to_reneg->size;
154 if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
155 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
159 for(i=0; i<ss_to_reneg.size; i++) {
161 (frescan_ss_t)vres_to_reneg->vres[i];
165 if (vres_to_cancel == NULL) {
166 ss_to_cancel.size = 0;
168 ss_to_cancel.size = vres_to_cancel->size;
169 if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
170 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
174 for(i=0; i<ss_to_cancel.size; i++) {
176 (frescan_ss_t)vres_to_cancel->vres[i];
180 if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
181 FRESCAN_ERROR("new_vres is NULL\n");
186 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
187 "calling frescan_bwres_group_change_mode_sync\n");
189 ret = frescan_bwres_group_change_mode_sync
190 ((frescan_network_t)resource_id,
197 if (ret != 0) return -1;
199 if (accepted == false) {
200 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
201 return -1; // TODO: change to constant FNA_REJECTED
204 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
205 // convert new ss to fna_vres
206 if (contracts_to_neg != NULL) {
207 new_vres->size = ss_new.size;
208 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
209 "new_vres->size:%d\n", new_vres->size);
210 for(i=0; i<new_vres->size; i++) {
211 new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
212 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
213 "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
221 * frescan_fna_contract_negotiate()
223 * The operation negotiates a contract and if accepted it will return
224 * a fna_vres_id_t. It will also check that the given contract_id is unique
225 * within the network.
227 * If the on-line admission test is enabled, it determines whether the
228 * contract can be admitted or not based on the current contracts
229 * established in the network. Then it creates the vres and
230 * recalculates all necessary parameters for the contracts already
231 * present in the system.
233 * This is a potentially blocking operation, it returns when the
234 * system has either rejected the contract, or admitted it and made it
237 * @param[in] resource_id The network we are referring to (a protocol
238 * could be able to handle several networks at the same time)
239 * @param[in] contract The contract parameters to negotiate
240 * @param[out] vres The internal virtual resource id
243 * 0 if there are no errors (in this case it also means contract accepted) \n
244 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
245 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
246 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
247 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
248 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
249 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
250 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
253 int frescan_fna_contract_negotiate
254 (const frsh_resource_id_t resource_id,
255 const frsh_contract_t *contract,
259 frsh_contracts_group_t contracts_to_neg;
260 fna_vres_group_t new_vres;
262 contracts_to_neg.size = 1;
263 contracts_to_neg.contracts[0] = *contract;
265 ret = frescan_fna_group_change_mode_sync
266 (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
267 if (ret != 0) return ret;
269 *vres = new_vres.vres[0];
274 * frescan_fna_contract_renegotiate_sync()
276 * The operation renegotiates a contract for an existing vres. If
277 * the on-line admission test is enabled it determines whether the
278 * contract can be admitted or not based on the current contracts
279 * established in the system. If it cannot be admitted, the old
280 * contract remains in effect and an error is returned. If it can be
281 * admitted, it recalculates all necessary parameters for the
282 * contracts already present in the system and returns zero. This is a
283 * potentially blocking operation; it returns when the system has
284 * either rejected the new contract, or admitted it and made it
287 * @param[in] resource_id The network we are referring to (a protocol
288 * could be able to handle several networks at the same time)
289 * @param[in] vres The internal virtual resource id to renegotiate
290 * @param[in] new_contract The new contract
293 * 0 if there are no errors (in this case it also means contract accepted) \n
294 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
295 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
296 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
297 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
298 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
299 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
300 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
303 int frescan_fna_contract_renegotiate_sync
304 (const frsh_resource_id_t resource_id,
305 const fna_vres_id_t vres,
306 const frsh_contract_t *new_contract)
308 frsh_contracts_group_t contracts_to_reneg;
309 fna_vres_group_t vres_to_reneg;
311 contracts_to_reneg.size = 1;
312 contracts_to_reneg.contracts[0] = *new_contract;
313 vres_to_reneg.size = 1;
314 vres_to_reneg.vres[0] = vres;
316 return frescan_fna_group_change_mode_sync
317 (resource_id, NULL, &contracts_to_reneg,
318 &vres_to_reneg, NULL, NULL);
322 * frescan_fna_contract_renegotiate_async()
324 * The operation enqueues a renegotiate operation for an existing
325 * vres, and returns immediately. The renegotiate operation is
326 * performed asynchronously, as soon as it is practical; meanwhile the
327 * system operation will continue normally. When the renegotiation is
328 * made, if the on-line admission test is enabled it determines
329 * whether the contract can be admitted or not based on the current
330 * contracts established in the system. If it cannot be admitted, the
331 * old contract remains in effect. If it can be admitted, it
332 * recalculates all necessary parameters for the contracts already
333 * present in the system.
335 * When the operation is completed, notification is made to the
336 * caller, if requested, via a signal. The status of the operation (in
337 * progress, admitted, rejected) can be checked with the
338 * frsh_vres_get_renegotiation_status() operation. The argument
339 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
340 * signal value and in this case signal_info is to be sent with the signal.
342 * @param[in] resource_id The network we are referring to (a protocol
343 * could be able to handle several networks at the same time)
344 * @param[in] vres The internal virtual resource id to renegotiate
345 * @param[in] new_contract The new contract
346 * @param[in] signal_to_notify Signal number to use to notify vres of
347 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
348 * @param[in] signal_info: Associated info that will come with the signal.
349 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
352 * 0 if there are no errors \n
353 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
354 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
355 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
356 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
357 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
358 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
359 * NULL nor a valid POSIX signal \n
362 int frescan_fna_contract_renegotiate_async
363 (const frsh_resource_id_t resource_id,
364 const fna_vres_id_t vres,
365 const frsh_contract_t *new_contract,
366 frsh_signal_t signal_to_notify,
367 frsh_signal_info_t signal_info)
369 FRESCAN_ERROR("not implemented\n");
374 * frescan_fna_vres_get_renegotiation_status()
376 * The operation reports on the status of the last renegotiation
377 * operation enqueued for the specified vres. It is callable even
378 * after notification of the completion of such operation, if
381 * If the vres is not and has not been involved in any of the
382 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
383 * operations, the status returned is FNA_NOT_REQUESTED
385 * @param[in] resource_id The network we are referring to (a protocol
386 * could be able to handle several networks at the same time)
387 * @param[in] vres The internal virtual resource id we want the status from
388 * @param[in] renegotiation_status The status of the last renegotiation on
389 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
390 * FRSH_RS_NOT_REQUESTED)
393 * 0 if there are no errors \n
394 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
395 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
396 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
397 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
398 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
401 int frescan_fna_vres_get_renegotiation_status
402 (const frsh_resource_id_t resource_id,
403 const fna_vres_id_t vres,
404 frsh_renegotiation_status_t *renegotiation_status)
406 FRESCAN_ERROR("not implemented\n");
411 * frescan_fna_vres_destroy()
413 * The operation eliminates the specified vres
414 * and recalculates all necessary parameters for the contracts
415 * remaining in the system. This is a potentially blocking operation;
416 * it returns when the system has made the changes effective.
418 * @param[in] resource_id The network we are referring to (a protocol
419 * could be able to handle several networks at the same time)
420 * @param[in] vres The internal virtual resource id to destroy
423 * 0 if there are no errors \n
424 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
425 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
426 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
427 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
428 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
431 int frescan_fna_vres_destroy
432 (const frsh_resource_id_t resource_id,
433 const fna_vres_id_t vres)
435 fna_vres_group_t vres_to_cancel;
437 vres_to_cancel.size = 1;
438 vres_to_cancel.vres[0] = vres;
440 return frescan_fna_group_change_mode_sync
441 (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
445 * frescan_fna_vres_get_contract()
447 * This operation stores the contract parameters currently associated
448 * with the specified vres in the variable pointed to by
449 * contract. It returns an error if the vres_id is not recognised.
451 * @param[in] resource_id The network we are referring to (a protocol
452 * could be able to handle several networks at the same time)
453 * @param[in] vres The internal virtual resource id
454 * @param[out] contract The contract parameters that we want
457 * 0 if there are no errors \n
458 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
459 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
460 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
461 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
462 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
465 int frescan_fna_vres_get_contract
466 (const frsh_resource_id_t resource_id,
467 const fna_vres_id_t vres,
468 frsh_contract_t *contract)
470 FRESCAN_ERROR("not implemented\n");
475 * frescan_fna_vres_get_usage()
477 * This function gets the execution time spent by all messages that have been
478 * sent through the specified vres.
480 * @param[in] resource_id The network we are referring to (a protocol
481 * could be able to handle several networks at the same time)
482 * @param[in] vres The internal virtual resource id
483 * @param[out] usage Execution time spent by this vres
486 * 0 if there are no errors \n
487 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
488 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
489 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
490 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
491 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
494 int frescan_fna_vres_get_usage
495 (const frsh_resource_id_t resource_id,
496 const fna_vres_id_t vres,
497 struct timespec *usage)
499 FRESCAN_ERROR("not implemented\n");
504 * frescan_fna_vres_get_remaining_budget()
506 * This function stores in the variable pointed to by budget the
507 * remaining execution-time budget associated with the specified
508 * vres in the present period.
510 * @param[in] resource_id The network we are referring to (a protocol
511 * could be able to handle several networks at the same time)
512 * @param[in] vres The internal virtual resource id
513 * @param[out] remaining_budget The remaining budget for this period
516 * 0 if there are no errors \n
517 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
518 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
519 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
520 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
521 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
524 int frescan_fna_vres_get_remaining_budget
525 (const frsh_resource_id_t resource_id,
526 const fna_vres_id_t vres,
527 struct timespec *remaining_budget)
529 FRESCAN_ERROR("not implemented\n");
534 * frescan_fna_vres_get_budget_and_period()
536 * This function gets the budget and period associated with the specified vres
537 * for each period. If one of these pointers is NULL, the corresponding
538 * information is not stored.
540 * @param[in] resource_id The network we are referring to (a protocol
541 * could be able to handle several networks at the same time)
542 * @param[in] vres The internal virtual resource id
543 * @param[out] budget The budget associated to vres
544 * @param[out] period The period associated to vres
547 * 0 if there are no errors \n
548 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
549 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
550 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
551 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
552 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
555 int frescan_fna_vres_get_budget_and_period
556 (const frsh_resource_id_t resource_id,
557 const fna_vres_id_t vres,
558 struct timespec *budget,
559 struct timespec *period)
562 frescan_server_params_t server_params;
564 ret = frescan_servers_get_data((frescan_network_t)resource_id,
567 if (ret != 0) return ret;
569 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
570 server_params.budget);
572 *period = server_params.period;
574 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
575 "budget(%d packets %ld us\n",
576 server_params.budget, frsh_rel_time_to_usec(*budget));
583 ///////////////////////////////////////////////////////////////////
584 // SPARE CAPACITY FUNCIONS
585 ///////////////////////////////////////////////////////////////////
588 * @defgroup fnaspare FNA Spare Capacity
591 * The following functions are used to get spare capacity data
597 * frescan_fna_resource_get_capacity()
599 * This operation gets the spare capacity currently assigned to a importance
600 * level. If we divide this value by UINT32_MAX we will get the network
601 * utilization associated to the spare capacity of a importance level.
603 * The following is typically in stdint.h: \n
604 * - typedef unsigned int uint32_t; \n
605 * - # define UINT32_MAX (4294967295U) \n
607 * @param[in] resource_id The network we are referring to (a protocol
608 * could be able to handle several networks at the same time)
609 * @param[in] importance The importance we want the capacity of
610 * @param[out] capacity The spare capacity for that importance level
613 * 0 if there are no errors \n
614 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
615 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
616 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
617 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
620 int frescan_fna_resource_get_capacity
621 (const frsh_resource_id_t resource_id,
622 const int importance,
625 FRESCAN_ERROR("not implemented\n");
630 * frescan_fna_resource_get_total_weight()
632 * This function gets the sum of the weight parameters for all vres in a
633 * network of an importance level.
635 * @param[in] resource_id The network we are referring to (a protocol
636 * could be able to handle several networks at the same time)
637 * @param[in] importance The importance we want the total weight of
638 * @param[out] total_weight The total weight for that importance level
641 * 0 if there are no errors \n
642 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
643 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
644 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
645 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
648 int frescan_fna_resource_get_total_weight
649 (const frsh_resource_id_t resource_id,
650 const int importance,
653 FRESCAN_ERROR("not implemented\n");
658 * frescan_fna_vres_decrease_capacity()
660 * This function allows to ask for less budget and period than what we
661 * received. The request must be compatible with the rest of contract
662 * parameters of the vres. If we want to recover the released capacity
663 * we will need to renegotiate.
665 * @param[in] resource_id The network we are referring to (a protocol
666 * could be able to handle several networks at the same time)
667 * @param[in] vres The internal virtual resource id
668 * @param[in] new_budget The new_budget
669 * @param[in] new_period The new Period
672 * 0 if there are no errors \n
673 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
674 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
675 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
676 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
677 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
678 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
682 int frescan_fna_vres_decrease_capacity
683 (const frsh_resource_id_t resource_id,
684 const fna_vres_id_t vres,
685 const struct timespec new_budget,
686 const struct timespec new_period)
688 FRESCAN_ERROR("not implemented\n");
692 ///////////////////////////////////////////////////////////////////
693 // SEND RECEIVE OPERATIONS
694 ///////////////////////////////////////////////////////////////////
697 * frescan_fna_send_sync()
699 * Similar to previous function but now the sending thread gets blocked
700 * until the message is already sent to the network.
702 * @param[in] endpoint The send endpoint we are sending through. It must
703 * be bound to a virtual resource (resource_id is in the endpoint).
704 * @param[in] msg The message we want to send
705 * @param[in] size The size in bytes of the message
708 * 0 if there are no errors \n
709 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
710 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
711 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
712 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
713 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
714 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
715 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
716 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
719 int frescan_fna_send_sync
720 (const fna_endpoint_data_t *endpoint,
724 FRESCAN_ERROR("not implemented\n");
729 * frescan_fna_send_async()
731 * This operation sends a message stored in msg and of length size
732 * through the given send endpoint. The operation is non-blocking and
733 * returns immediately.
735 * @param[in] endpoint The send endpoint we are sending through. It must
736 * be bound to a virtual resource (resource_id is in the endpoint).
737 * @param[in] msg The message we want to send
738 * @param[in] size The size in bytes of the message
741 * 0 if there are no errors \n
742 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
743 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
744 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
745 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
746 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
747 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
748 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
749 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
752 int frescan_fna_send_async
753 (const fna_endpoint_data_t *endpoint,
758 frescan_send_params_t params;
760 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
761 "net:%u dest:%u chan:%u size:%u ss:%u\n",
762 endpoint->resource_id, endpoint->destination,
763 endpoint->stream_id, size, endpoint->vres);
765 params.net = (frescan_network_t)endpoint->resource_id;
766 params.to = (frescan_node_t)endpoint->destination;
767 params.channel = (frescan_channel_t)endpoint->stream_id;
768 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
769 params.ss = endpoint->vres;
771 ret = frescan_send(¶ms, (uint8_t *)msg, size);
773 FRESCAN_ERROR ("could not send message\n");
781 * frescan_fna_receive_sync()
783 * This operation is used to receive messages from the network with a
784 * blocking behavior (if there are no messages this operation blocks
785 * the calling thread).
787 * When a message is available, it is copied to buffer (up to its size).
788 * The number of bytes copied is returned in received_bytes. The rest
789 * of the bytes of that message will be lost or not depending on the
790 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
792 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
793 * too small for the message received. In this case the message is
796 * Messages arriving at a receiver buffer that is full will be handled
797 * according to the queueing policy of the endpoint (overwrite oldest,
800 * @param[in] endpoint The receive endpoint we are receiving from.
801 * (resource_id is in the endpoint).
802 * @param[out] buffer Buffer for storing the received message
803 * @param[in] buffer_size The size in bytes of this buffer
804 * @param[out] received_bytes The actual number of received bytes
805 * @param[out] from Address of the sender node
808 * 0 if there are no errors \n
809 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
810 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
811 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
812 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
813 * FNA_ERR_NO_SPACE: if the message size is bigger than the
814 * provided buffer. \n
817 int frescan_fna_receive_sync
818 (const fna_endpoint_data_t *endpoint,
820 const size_t buffer_size,
821 size_t *received_bytes,
822 frsh_network_address_t *from)
825 frescan_recv_params_t params;
826 frescan_node_t frescan_from;
829 params.net = (frescan_network_t)endpoint->resource_id;
830 params.channel = (frescan_channel_t)endpoint->stream_id;
831 params.flags = FRESCAN_SYNC;
833 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
834 "net:%u chan:%u size:%u\n",
835 endpoint->resource_id, endpoint->stream_id, buffer_size);
837 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
838 received_bytes, &frescan_from, &prio);
841 FRESCAN_ERROR ("error while receiving message");
845 *from = (frsh_network_address_t)frescan_from;
847 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
848 "msg received, from:%u bytes:%u prio:%u\n",
849 *from, *received_bytes, prio);
855 * frescan_fna_receive_async()
857 * This operation is similar to the previous one but it works in a non
858 * blocking (asynchronous) fashion. If no message is available it
859 * returns with error FNA_NO_MESSAGE.
861 * @param[in] endpoint The receive endpoint we are receiving from.
862 * (resource_id is in the endpoint).
863 * @param[out] buffer Buffer for storing the received message
864 * @param[in] buffer_size The size in bytes of this buffer
865 * @param[out] received_bytes The actual number of received bytes
866 * @param[out] from Address of the sender node
869 * 0 if there are no errors \n
870 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
871 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
872 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
873 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
874 * FNA_ERR_NO_SPACE: if the message size is bigger than the
875 * provided buffer. \n
876 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
879 int frescan_fna_receive_async
880 (const fna_endpoint_data_t *endpoint,
882 const size_t buffer_size,
883 size_t *received_bytes,
884 frsh_network_address_t *from)
886 FRESCAN_ERROR("not implemented\n");
891 * frescan_fna_send_endpoint_get_status()
893 * This function tells the number of messages still pending in the
894 * endpoint queue, whether the network is up or down with some
895 * optional information which is protocol_dependent.
897 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
898 * @param[out] number_of_pending_messages The number of pending messages
899 * @param[out] network_status How is the network (up, down..)
900 * @param[out] protocol_status Protocol dependent status info
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
910 int frescan_fna_send_endpoint_get_status
911 (const fna_endpoint_data_t *endpoint,
912 int *number_of_pending_messages,
913 frsh_endpoint_network_status_t *network_status,
914 frsh_protocol_status_t *protocol_status)
916 FRESCAN_ERROR("not implemented\n");
921 * frescan_fna_receive_endpoint_created()
923 * This operation is a called from frsh_receive_endpoint_create with a
924 * receive_endpoint structure already filled.
926 * Receiving endpoints are not bound to any network vres, this is
927 * because don't originate any traffic.
929 * @param[in] endpoint the endpoint object.
932 * 0 if there are no errors \n
933 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
934 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
935 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
936 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
938 int frescan_fna_receive_endpoint_created
939 (fna_endpoint_data_t *endpoint)
941 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
946 * frescan_fna_receive_endpoint_get_pending_messages
948 * This function tells the number of messages still pending in the
949 * endpoint queue, whether the network is up or down and some optional
950 * information which is protocol dependent.
952 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
953 * @param[out] number_of_pending_messages The number of pending messages
954 * @param[out] network_status How is the network (up, down..)
955 * @param[out] protocol_status Protocol dependent status info
958 * 0 if there are no errors \n
959 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
960 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
961 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
962 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
965 int frescan_fna_receive_endpoint_get_status
966 (const fna_endpoint_data_t *endpoint,
967 int *number_of_pending_messages,
968 frsh_endpoint_network_status_t *network_status,
969 frsh_protocol_status_t *protocol_status)
971 FRESCAN_ERROR("not implemented\n");
975 //////////////////////////////////////////////////////////////////////
976 // NETWORK CONFIGURATION FUNCTIONS
977 //////////////////////////////////////////////////////////////////////
980 * frescan_fna_network_get_max_message_size()
982 * This operation gives the maximum number of bytes that can be sent
983 * at a time through the send function when using the network designated by
984 * 'resource_id' and sending it to 'destination'.
986 * If the application needs to send bigger messages it will have to
989 * Some protocols, like IP, are capable of sending large messages
990 * (and use fragmentation internally) but other protocols don't.
992 * @param[in] resource_id The network we want the tx time from.
993 * @param[in] destination The destination address
994 * @param[out] max_size The maximum number of bytes for each message
997 * 0 if there are no errors \n
998 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
999 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1000 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1001 * a network accessible from the current processing node \n
1002 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
1006 int frescan_fna_network_get_max_message_size
1007 (const frsh_resource_id_t resource_id,
1008 const frsh_network_address_t destination,
1011 FRESCAN_ERROR("not implemented\n");
1016 * frescan_fna_network_bytes_to_budget()
1018 * This operation converts a number of bytes into a temporal budget for
1019 * a specific network. Network overheads are not included here but are
1020 * considered internally when negotiating a specific contract.
1022 * @param[in] resource_id The network
1023 * @param[in] nbytes Number of bytes
1024 * @param[out] budget The network budget for nbytes
1027 * 0 if there are no errors \n
1028 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1029 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1030 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1031 * a network accessible from the current processing node \n
1032 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
1036 int frescan_fna_network_bytes_to_budget
1037 (const frsh_resource_id_t resource_id,
1038 const size_t nbytes,
1039 frsh_rel_time_t *budget)
1041 int number_of_packets;
1043 if (budget == NULL || nbytes < 0) {
1047 // number of FRESCAN frames (8 bytes)
1048 number_of_packets = (int) ceil((double)nbytes / 8.0);
1049 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
1052 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
1053 "bytes: %d -> budget: %ld us\n",
1054 nbytes, frsh_rel_time_to_usec(*budget));
1060 * frescan_fna_network_budget_to_bytes()
1062 * This operation converts a temporal budget into a number of bytes for
1063 * a specific network. Network overheads are not included.
1065 * @param[in] resource_id The network
1066 * @param[in] budget The network budget for nbytes
1067 * @param[out] nbytes Number of bytes
1070 * 0 if there are no errors \n
1071 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1072 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1073 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1074 * a network accessible from the current processing node \n
1075 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
1076 * an invalid time value \n
1079 int frescan_fna_network_budget_to_bytes
1080 (const frsh_resource_id_t resource_id,
1081 const frsh_rel_time_t *budget,
1084 int number_of_packets;
1086 if (budget == NULL || nbytes == NULL) {
1090 number_of_packets = frsh_rel_time_to_usec(*budget) /
1091 FRESCAN_FRAME_TX_TIME_US;
1093 *nbytes = number_of_packets * 8;
1099 * frescan_fna_network_get_min_eff_budget()
1101 * This operation gets the minimum effective budget for a network. Each message
1102 * consumes a contracted budget in "chunks" (i.e: packets) that we call
1103 * minimum effective budget.
1105 * A negotiated contract, for N bytes in a period T, means that there is a
1106 * virtual resource that reserves for the user:
1108 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1110 * Note that if the user decides not to send these N bytes at once but, say,
1111 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1112 * budget will become exhausted before sending all the bytes.
1114 * @param[in] resource_id The network
1115 * @param[out] budget The network budget
1118 * 0 if there are no errors \n
1119 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1120 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1121 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1122 * a network accessible from the current processing node \n
1123 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1126 int frescan_fna_network_get_min_eff_budget
1127 (const frsh_resource_id_t resource_id,
1128 struct timespec *budget)
1130 if (budget == NULL) {
1134 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1139 // GLOBAL variable to install the network protocol in FRESCOR
1141 fna_operations_t frescan_fna_operations = {
1142 #ifdef CONFIG_FNA_FRESCAN_CONNECTED
1143 .fna_init = frescan_fna_init,
1144 .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
1145 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1146 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1147 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1148 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1149 .fna_vres_destroy = frescan_fna_vres_destroy,
1150 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1151 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1152 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1153 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1154 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1155 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1156 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1157 .fna_send_sync = frescan_fna_send_sync,
1158 .fna_send_async = frescan_fna_send_async,
1159 .fna_receive_sync = frescan_fna_receive_sync,
1160 .fna_receive_async = frescan_fna_receive_async,
1161 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1162 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1163 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1165 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1166 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1167 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1168 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget