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 */
74 #include "frescan_servers.h"
76 //////////////////////////////////////////////////////////////////////
78 //////////////////////////////////////////////////////////////////////
83 * This function will be hooked to the frsh_init function and it is
84 * intented to initialize the protocol and its structures.
86 * @param[in] resource_id The network we are referring to (a protocol
87 * could be able to handle several networks at the same time)
90 * 0 if there are no errors \n
91 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
92 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
93 * FNA_ERR_ALREADY_INITIALIZED:
94 * if the function has already been called before (with success) \n
97 int frescan_fna_init(const frsh_resource_id_t resource_id)
100 frescan_init_params_t init_params;
102 // TODO: resource_id must be relative or sth
103 // TODO: init_params must be configurable
104 init_params.net = 0; // (frescan_network_t)resource_id;
105 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
106 init_params.tx_fp_max_prio = 10;
107 init_params.rx_num_of_channels = 10;
108 init_params.rx_channel_max_prio = NULL;
110 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
111 "Initializing FRESCAN FNA node%u\n", FRSH_CPU_ID_DEFAULT);
113 ret = frescan_init(&init_params);
114 if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
116 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
118 ret = frescan_bwres_init(init_params.net);
119 if (ret != 0) FRESCAN_ERROR ("could not init BWRES");
124 ///////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////
128 int frescan_fna_group_change_mode_sync
129 (const frsh_resource_id_t resource_id,
130 const frsh_contracts_group_t *contracts_to_neg,
131 const frsh_contracts_group_t *contracts_to_reneg,
132 const fna_vres_group_t *vres_to_reneg,
133 const fna_vres_group_t *vres_to_cancel,
134 fna_vres_group_t *new_vres)
138 frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
140 // convert fna_vres to ss
141 if (vres_to_reneg == NULL) {
142 ss_to_reneg.size = 0;
144 ss_to_reneg.size = vres_to_reneg->size;
145 if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
146 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
150 for(i=0; i<ss_to_reneg.size; i++) {
152 (frescan_ss_t)vres_to_reneg->vres[i];
156 if (vres_to_cancel == NULL) {
157 ss_to_cancel.size = 0;
159 ss_to_cancel.size = vres_to_cancel->size;
160 if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
161 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
165 for(i=0; i<ss_to_cancel.size; i++) {
167 (frescan_ss_t)vres_to_cancel->vres[i];
171 if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
172 FRESCAN_ERROR("new_vres is NULL\n");
177 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
178 "calling frescan_bwres_group_change_mode_sync\n");
180 ret = frescan_bwres_group_change_mode_sync
181 ((frescan_network_t)resource_id,
188 if (ret != 0) return -1;
190 if (accepted == false) {
191 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
192 return -1; // TODO: change to constant FNA_REJECTED
195 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 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
200 "new_vres->size:%d\n", new_vres->size);
201 for(i=0; i<new_vres->size; i++) {
202 new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
203 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
204 "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
212 * frescan_fna_contract_negotiate()
214 * The operation negotiates a contract and if accepted it will return
215 * a fna_vres_id_t. It will also check that the given contract_id is unique
216 * within the network.
218 * If the on-line admission test is enabled, it determines whether the
219 * contract can be admitted or not based on the current contracts
220 * established in the network. Then it creates the vres and
221 * recalculates all necessary parameters for the contracts already
222 * present in the system.
224 * This is a potentially blocking operation, it returns when the
225 * system has either rejected the contract, or admitted it and made it
228 * @param[in] resource_id The network we are referring to (a protocol
229 * could be able to handle several networks at the same time)
230 * @param[in] contract The contract parameters to negotiate
231 * @param[out] vres The internal virtual resource id
234 * 0 if there are no errors (in this case it also means contract accepted) \n
235 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
236 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
237 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
238 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
239 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
240 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
241 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
244 int frescan_fna_contract_negotiate
245 (const frsh_resource_id_t resource_id,
246 const frsh_contract_t *contract,
250 frsh_contracts_group_t contracts_to_neg;
251 fna_vres_group_t new_vres;
253 contracts_to_neg.size = 1;
254 contracts_to_neg.contracts[0] = *contract;
256 ret = frescan_fna_group_change_mode_sync
257 (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
258 if (ret != 0) return ret;
260 *vres = new_vres.vres[0];
265 * frescan_fna_contract_renegotiate_sync()
267 * The operation renegotiates a contract for an existing vres. If
268 * the on-line admission test is enabled it determines whether the
269 * contract can be admitted or not based on the current contracts
270 * established in the system. If it cannot be admitted, the old
271 * contract remains in effect and an error is returned. If it can be
272 * admitted, it recalculates all necessary parameters for the
273 * contracts already present in the system and returns zero. This is a
274 * potentially blocking operation; it returns when the system has
275 * either rejected the new contract, or admitted it and made it
278 * @param[in] resource_id The network we are referring to (a protocol
279 * could be able to handle several networks at the same time)
280 * @param[in] vres The internal virtual resource id to renegotiate
281 * @param[in] new_contract The new contract
284 * 0 if there are no errors (in this case it also means contract accepted) \n
285 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
286 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
287 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
288 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
289 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
290 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
291 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
294 int frescan_fna_contract_renegotiate_sync
295 (const frsh_resource_id_t resource_id,
296 const fna_vres_id_t vres,
297 const frsh_contract_t *new_contract)
299 frsh_contracts_group_t contracts_to_reneg;
300 fna_vres_group_t vres_to_reneg;
302 contracts_to_reneg.size = 1;
303 contracts_to_reneg.contracts[0] = *new_contract;
304 vres_to_reneg.size = 1;
305 vres_to_reneg.vres[0] = vres;
307 return frescan_fna_group_change_mode_sync
308 (resource_id, NULL, &contracts_to_reneg,
309 &vres_to_reneg, NULL, NULL);
313 * frescan_fna_contract_renegotiate_async()
315 * The operation enqueues a renegotiate operation for an existing
316 * vres, and returns immediately. The renegotiate operation is
317 * performed asynchronously, as soon as it is practical; meanwhile the
318 * system operation will continue normally. When the renegotiation is
319 * made, if the on-line admission test is enabled it determines
320 * whether the contract can be admitted or not based on the current
321 * contracts established in the system. If it cannot be admitted, the
322 * old contract remains in effect. If it can be admitted, it
323 * recalculates all necessary parameters for the contracts already
324 * present in the system.
326 * When the operation is completed, notification is made to the
327 * caller, if requested, via a signal. The status of the operation (in
328 * progress, admitted, rejected) can be checked with the
329 * frsh_vres_get_renegotiation_status() operation. The argument
330 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
331 * signal value and in this case signal_info is to be sent with the signal.
333 * @param[in] resource_id The network we are referring to (a protocol
334 * could be able to handle several networks at the same time)
335 * @param[in] vres The internal virtual resource id to renegotiate
336 * @param[in] new_contract The new contract
337 * @param[in] signal_to_notify Signal number to use to notify vres of
338 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
339 * @param[in] signal_info: Associated info that will come with the signal.
340 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
343 * 0 if there are no errors \n
344 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
345 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
346 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
347 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
348 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
349 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
350 * NULL nor a valid POSIX signal \n
353 int frescan_fna_contract_renegotiate_async
354 (const frsh_resource_id_t resource_id,
355 const fna_vres_id_t vres,
356 const frsh_contract_t *new_contract,
357 frsh_signal_t signal_to_notify,
358 frsh_signal_info_t signal_info)
360 FRESCAN_ERROR("not implemented\n");
365 * frescan_fna_vres_get_renegotiation_status()
367 * The operation reports on the status of the last renegotiation
368 * operation enqueued for the specified vres. It is callable even
369 * after notification of the completion of such operation, if
372 * If the vres is not and has not been involved in any of the
373 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
374 * operations, the status returned is FNA_NOT_REQUESTED
376 * @param[in] resource_id The network we are referring to (a protocol
377 * could be able to handle several networks at the same time)
378 * @param[in] vres The internal virtual resource id we want the status from
379 * @param[in] renegotiation_status The status of the last renegotiation on
380 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
381 * FRSH_RS_NOT_REQUESTED)
384 * 0 if there are no errors \n
385 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
386 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
387 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
388 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
389 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
392 int frescan_fna_vres_get_renegotiation_status
393 (const frsh_resource_id_t resource_id,
394 const fna_vres_id_t vres,
395 frsh_renegotiation_status_t *renegotiation_status)
397 FRESCAN_ERROR("not implemented\n");
402 * frescan_fna_vres_destroy()
404 * The operation eliminates the specified vres
405 * and recalculates all necessary parameters for the contracts
406 * remaining in the system. This is a potentially blocking operation;
407 * it returns when the system has made the changes effective.
409 * @param[in] resource_id The network we are referring to (a protocol
410 * could be able to handle several networks at the same time)
411 * @param[in] vres The internal virtual resource id to destroy
414 * 0 if there are no errors \n
415 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
416 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
417 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
418 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
419 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
422 int frescan_fna_vres_destroy
423 (const frsh_resource_id_t resource_id,
424 const fna_vres_id_t vres)
426 fna_vres_group_t vres_to_cancel;
428 vres_to_cancel.size = 1;
429 vres_to_cancel.vres[0] = vres;
431 return frescan_fna_group_change_mode_sync
432 (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
436 * frescan_fna_vres_get_contract()
438 * This operation stores the contract parameters currently associated
439 * with the specified vres in the variable pointed to by
440 * contract. It returns an error if the vres_id is not recognised.
442 * @param[in] resource_id The network we are referring to (a protocol
443 * could be able to handle several networks at the same time)
444 * @param[in] vres The internal virtual resource id
445 * @param[out] contract The contract parameters that we want
448 * 0 if there are no errors \n
449 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
450 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
451 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
452 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
453 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
456 int frescan_fna_vres_get_contract
457 (const frsh_resource_id_t resource_id,
458 const fna_vres_id_t vres,
459 frsh_contract_t *contract)
461 FRESCAN_ERROR("not implemented\n");
466 * frescan_fna_vres_get_usage()
468 * This function gets the execution time spent by all messages that have been
469 * sent through the specified vres.
471 * @param[in] resource_id The network we are referring to (a protocol
472 * could be able to handle several networks at the same time)
473 * @param[in] vres The internal virtual resource id
474 * @param[out] usage Execution time spent by this vres
477 * 0 if there are no errors \n
478 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
479 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
480 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
481 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
482 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
485 int frescan_fna_vres_get_usage
486 (const frsh_resource_id_t resource_id,
487 const fna_vres_id_t vres,
488 struct timespec *usage)
490 FRESCAN_ERROR("not implemented\n");
495 * frescan_fna_vres_get_remaining_budget()
497 * This function stores in the variable pointed to by budget the
498 * remaining execution-time budget associated with the specified
499 * vres in the present period.
501 * @param[in] resource_id The network we are referring to (a protocol
502 * could be able to handle several networks at the same time)
503 * @param[in] vres The internal virtual resource id
504 * @param[out] remaining_budget The remaining budget for this period
507 * 0 if there are no errors \n
508 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
509 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
510 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
511 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
512 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
515 int frescan_fna_vres_get_remaining_budget
516 (const frsh_resource_id_t resource_id,
517 const fna_vres_id_t vres,
518 struct timespec *remaining_budget)
520 FRESCAN_ERROR("not implemented\n");
525 * frescan_fna_vres_get_budget_and_period()
527 * This function gets the budget and period associated with the specified vres
528 * for each period. If one of these pointers is NULL, the corresponding
529 * information is not stored.
531 * @param[in] resource_id The network we are referring to (a protocol
532 * could be able to handle several networks at the same time)
533 * @param[in] vres The internal virtual resource id
534 * @param[out] budget The budget associated to vres
535 * @param[out] period The period associated to vres
538 * 0 if there are no errors \n
539 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
540 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \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 both pointers are NULL \n
546 int frescan_fna_vres_get_budget_and_period
547 (const frsh_resource_id_t resource_id,
548 const fna_vres_id_t vres,
549 struct timespec *budget,
550 struct timespec *period)
553 frescan_server_params_t server_params;
555 ret = frescan_servers_get_data((frescan_network_t)resource_id,
558 if (ret != 0) return ret;
560 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
561 server_params.budget);
563 *period = server_params.period;
565 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
566 "budget(%d packets %ld us\n",
567 server_params.budget, frsh_rel_time_to_usec(*budget));
574 ///////////////////////////////////////////////////////////////////
575 // SPARE CAPACITY FUNCIONS
576 ///////////////////////////////////////////////////////////////////
579 * @defgroup fnaspare FNA Spare Capacity
582 * The following functions are used to get spare capacity data
588 * frescan_fna_resource_get_capacity()
590 * This operation gets the spare capacity currently assigned to a importance
591 * level. If we divide this value by UINT32_MAX we will get the network
592 * utilization associated to the spare capacity of a importance level.
594 * The following is typically in stdint.h: \n
595 * - typedef unsigned int uint32_t; \n
596 * - # define UINT32_MAX (4294967295U) \n
598 * @param[in] resource_id The network we are referring to (a protocol
599 * could be able to handle several networks at the same time)
600 * @param[in] importance The importance we want the capacity of
601 * @param[out] capacity The spare capacity for that importance level
604 * 0 if there are no errors \n
605 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
606 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
607 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
608 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
611 int frescan_fna_resource_get_capacity
612 (const frsh_resource_id_t resource_id,
613 const int importance,
616 FRESCAN_ERROR("not implemented\n");
621 * frescan_fna_resource_get_total_weight()
623 * This function gets the sum of the weight parameters for all vres in a
624 * network of an importance level.
626 * @param[in] resource_id The network we are referring to (a protocol
627 * could be able to handle several networks at the same time)
628 * @param[in] importance The importance we want the total weight of
629 * @param[out] total_weight The total weight for that importance level
632 * 0 if there are no errors \n
633 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
634 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
635 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
636 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
639 int frescan_fna_resource_get_total_weight
640 (const frsh_resource_id_t resource_id,
641 const int importance,
644 FRESCAN_ERROR("not implemented\n");
649 * frescan_fna_vres_decrease_capacity()
651 * This function allows to ask for less budget and period than what we
652 * received. The request must be compatible with the rest of contract
653 * parameters of the vres. If we want to recover the released capacity
654 * we will need to renegotiate.
656 * @param[in] resource_id The network we are referring to (a protocol
657 * could be able to handle several networks at the same time)
658 * @param[in] vres The internal virtual resource id
659 * @param[in] new_budget The new_budget
660 * @param[in] new_period The new Period
663 * 0 if there are no errors \n
664 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
665 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
666 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
667 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
668 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
669 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
673 int frescan_fna_vres_decrease_capacity
674 (const frsh_resource_id_t resource_id,
675 const fna_vres_id_t vres,
676 const struct timespec new_budget,
677 const struct timespec new_period)
679 FRESCAN_ERROR("not implemented\n");
683 ///////////////////////////////////////////////////////////////////
684 // SEND RECEIVE OPERATIONS
685 ///////////////////////////////////////////////////////////////////
688 * frescan_fna_send_sync()
690 * Similar to previous function but now the sending thread gets blocked
691 * until the message is already sent to the network.
693 * @param[in] endpoint The send endpoint we are sending through. It must
694 * be bound to a virtual resource (resource_id is in the endpoint).
695 * @param[in] msg The message we want to send
696 * @param[in] size The size in bytes of the message
699 * 0 if there are no errors \n
700 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
701 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
702 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
703 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
704 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
705 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
706 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
707 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
710 int frescan_fna_send_sync
711 (const fna_endpoint_data_t *endpoint,
715 FRESCAN_ERROR("not implemented\n");
720 * frescan_fna_send_async()
722 * This operation sends a message stored in msg and of length size
723 * through the given send endpoint. The operation is non-blocking and
724 * returns immediately.
726 * @param[in] endpoint The send endpoint we are sending through. It must
727 * be bound to a virtual resource (resource_id is in the endpoint).
728 * @param[in] msg The message we want to send
729 * @param[in] size The size in bytes of the message
732 * 0 if there are no errors \n
733 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
734 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
735 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
736 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
737 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
738 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
739 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
740 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
743 int frescan_fna_send_async
744 (const fna_endpoint_data_t *endpoint,
749 frescan_send_params_t params;
751 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
752 "net:%u dest:%u chan:%u size:%u ss:%u\n",
753 endpoint->resource_id, endpoint->destination,
754 endpoint->stream_id, size, endpoint->vres);
756 params.net = (frescan_network_t)endpoint->resource_id;
757 params.to = (frescan_node_t)endpoint->destination;
758 params.channel = (frescan_channel_t)endpoint->stream_id;
759 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
760 params.ss = endpoint->vres;
762 ret = frescan_send(¶ms, (uint8_t *)msg, size);
764 FRESCAN_ERROR ("could not send message\n");
772 * frescan_fna_receive_sync()
774 * This operation is used to receive messages from the network with a
775 * blocking behavior (if there are no messages this operation blocks
776 * the calling thread).
778 * When a message is available, it is copied to buffer (up to its size).
779 * The number of bytes copied is returned in received_bytes. The rest
780 * of the bytes of that message will be lost or not depending on the
781 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
783 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
784 * too small for the message received. In this case the message is
787 * Messages arriving at a receiver buffer that is full will be handled
788 * according to the queueing policy of the endpoint (overwrite oldest,
791 * @param[in] endpoint The receive endpoint we are receiving from.
792 * (resource_id is in the endpoint).
793 * @param[out] buffer Buffer for storing the received message
794 * @param[in] buffer_size The size in bytes of this buffer
795 * @param[out] received_bytes The actual number of received bytes
796 * @param[out] from Address of the sender node
799 * 0 if there are no errors \n
800 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
801 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
802 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
803 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
804 * FNA_ERR_NO_SPACE: if the message size is bigger than the
805 * provided buffer. \n
808 int frescan_fna_receive_sync
809 (const fna_endpoint_data_t *endpoint,
811 const size_t buffer_size,
812 size_t *received_bytes,
813 frsh_network_address_t *from)
816 frescan_recv_params_t params;
817 frescan_node_t frescan_from;
820 params.net = (frescan_network_t)endpoint->resource_id;
821 params.channel = (frescan_channel_t)endpoint->stream_id;
822 params.flags = FRESCAN_SYNC;
824 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
825 "net:%u chan:%u size:%u\n",
826 endpoint->resource_id, endpoint->stream_id, buffer_size);
828 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
829 received_bytes, &frescan_from, &prio);
832 FRESCAN_ERROR ("error while receiving message");
836 *from = (frsh_network_address_t)frescan_from;
838 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
839 "msg received, from:%u bytes:%u prio:%u\n",
840 *from, *received_bytes, prio);
846 * frescan_fna_receive_async()
848 * This operation is similar to the previous one but it works in a non
849 * blocking (asynchronous) fashion. If no message is available it
850 * returns with error FNA_NO_MESSAGE.
852 * @param[in] endpoint The receive endpoint we are receiving from.
853 * (resource_id is in the endpoint).
854 * @param[out] buffer Buffer for storing the received message
855 * @param[in] buffer_size The size in bytes of this buffer
856 * @param[out] received_bytes The actual number of received bytes
857 * @param[out] from Address of the sender node
860 * 0 if there are no errors \n
861 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
862 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
863 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
864 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
865 * FNA_ERR_NO_SPACE: if the message size is bigger than the
866 * provided buffer. \n
867 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
870 int frescan_fna_receive_async
871 (const fna_endpoint_data_t *endpoint,
873 const size_t buffer_size,
874 size_t *received_bytes,
875 frsh_network_address_t *from)
877 FRESCAN_ERROR("not implemented\n");
882 * frescan_fna_send_endpoint_get_status()
884 * This function tells the number of messages still pending in the
885 * endpoint queue, whether the network is up or down with some
886 * optional information which is protocol_dependent.
888 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
889 * @param[out] number_of_pending_messages The number of pending messages
890 * @param[out] network_status How is the network (up, down..)
891 * @param[out] protocol_status Protocol dependent status info
894 * 0 if there are no errors \n
895 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
896 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
897 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
898 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
901 int frescan_fna_send_endpoint_get_status
902 (const fna_endpoint_data_t *endpoint,
903 int *number_of_pending_messages,
904 frsh_endpoint_network_status_t *network_status,
905 frsh_protocol_status_t *protocol_status)
907 FRESCAN_ERROR("not implemented\n");
912 * frescan_fna_receive_endpoint_created()
914 * This operation is a called from frsh_receive_endpoint_create with a
915 * receive_endpoint structure already filled.
917 * Receiving endpoints are not bound to any network vres, this is
918 * because don't originate any traffic.
920 * @param[in] endpoint the endpoint object.
923 * 0 if there are no errors \n
924 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
925 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
926 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
927 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
929 int frescan_fna_receive_endpoint_created
930 (fna_endpoint_data_t *endpoint)
932 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
937 * frescan_fna_receive_endpoint_get_pending_messages
939 * This function tells the number of messages still pending in the
940 * endpoint queue, whether the network is up or down and some optional
941 * information which is protocol dependent.
943 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
944 * @param[out] number_of_pending_messages The number of pending messages
945 * @param[out] network_status How is the network (up, down..)
946 * @param[out] protocol_status Protocol dependent status info
949 * 0 if there are no errors \n
950 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
951 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
952 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
953 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
956 int frescan_fna_receive_endpoint_get_status
957 (const fna_endpoint_data_t *endpoint,
958 int *number_of_pending_messages,
959 frsh_endpoint_network_status_t *network_status,
960 frsh_protocol_status_t *protocol_status)
962 FRESCAN_ERROR("not implemented\n");
966 //////////////////////////////////////////////////////////////////////
967 // NETWORK CONFIGURATION FUNCTIONS
968 //////////////////////////////////////////////////////////////////////
971 * frescan_fna_network_get_max_message_size()
973 * This operation gives the maximum number of bytes that can be sent
974 * at a time through the send function when using the network designated by
975 * 'resource_id' and sending it to 'destination'.
977 * If the application needs to send bigger messages it will have to
980 * Some protocols, like IP, are capable of sending large messages
981 * (and use fragmentation internally) but other protocols don't.
983 * @param[in] resource_id The network we want the tx time from.
984 * @param[in] destination The destination address
985 * @param[out] max_size The maximum number of bytes for each message
988 * 0 if there are no errors \n
989 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
990 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
991 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
992 * a network accessible from the current processing node \n
993 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
997 int frescan_fna_network_get_max_message_size
998 (const frsh_resource_id_t resource_id,
999 const frsh_network_address_t destination,
1002 FRESCAN_ERROR("not implemented\n");
1007 * frescan_fna_network_bytes_to_budget()
1009 * This operation converts a number of bytes into a temporal budget for
1010 * a specific network. Network overheads are not included here but are
1011 * considered internally when negotiating a specific contract.
1013 * @param[in] resource_id The network
1014 * @param[in] nbytes Number of bytes
1015 * @param[out] budget The network budget for nbytes
1018 * 0 if there are no errors \n
1019 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1020 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1021 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1022 * a network accessible from the current processing node \n
1023 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
1027 int frescan_fna_network_bytes_to_budget
1028 (const frsh_resource_id_t resource_id,
1029 const size_t nbytes,
1030 frsh_rel_time_t *budget)
1032 int number_of_packets;
1034 if (budget == NULL || nbytes < 0) {
1038 // number of FRESCAN frames (8 bytes)
1039 number_of_packets = (int) ceil((double)nbytes / 8.0);
1040 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
1043 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
1044 "bytes: %d -> budget: %ld us\n",
1045 nbytes, frsh_rel_time_to_usec(*budget));
1051 * frescan_fna_network_budget_to_bytes()
1053 * This operation converts a temporal budget into a number of bytes for
1054 * a specific network. Network overheads are not included.
1056 * @param[in] resource_id The network
1057 * @param[in] budget The network budget for nbytes
1058 * @param[out] nbytes Number of bytes
1061 * 0 if there are no errors \n
1062 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1063 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1064 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1065 * a network accessible from the current processing node \n
1066 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
1067 * an invalid time value \n
1070 int frescan_fna_network_budget_to_bytes
1071 (const frsh_resource_id_t resource_id,
1072 const frsh_rel_time_t *budget,
1075 int number_of_packets;
1077 if (budget == NULL || nbytes == NULL) {
1081 number_of_packets = frsh_rel_time_to_usec(*budget) /
1082 FRESCAN_FRAME_TX_TIME_US;
1084 *nbytes = number_of_packets * 8;
1090 * frescan_fna_network_get_min_eff_budget()
1092 * This operation gets the minimum effective budget for a network. Each message
1093 * consumes a contracted budget in "chunks" (i.e: packets) that we call
1094 * minimum effective budget.
1096 * A negotiated contract, for N bytes in a period T, means that there is a
1097 * virtual resource that reserves for the user:
1099 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1101 * Note that if the user decides not to send these N bytes at once but, say,
1102 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1103 * budget will become exhausted before sending all the bytes.
1105 * @param[in] resource_id The network
1106 * @param[out] budget The network budget
1109 * 0 if there are no errors \n
1110 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1111 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1112 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1113 * a network accessible from the current processing node \n
1114 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1117 int frescan_fna_network_get_min_eff_budget
1118 (const frsh_resource_id_t resource_id,
1119 struct timespec *budget)
1121 if (budget == NULL) {
1125 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1130 // GLOBAL variable to install the network protocol in FRESCOR
1132 fna_operations_t frescan_fna_operations = {
1133 .fna_init = frescan_fna_init,
1134 .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
1135 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1136 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1137 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1138 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1139 .fna_vres_destroy = frescan_fna_vres_destroy,
1140 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1141 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1142 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1143 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1144 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1145 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1146 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1147 .fna_send_sync = frescan_fna_send_sync,
1148 .fna_send_async = frescan_fna_send_async,
1149 .fna_receive_sync = frescan_fna_receive_sync,
1150 .fna_receive_async = frescan_fna_receive_async,
1151 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1152 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1153 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1154 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1155 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1156 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1157 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget