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 "frescan_config.h"
73 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
74 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
75 #include "frescan_servers.h"
77 //////////////////////////////////////////////////////////////////////
79 //////////////////////////////////////////////////////////////////////
84 * This function will be hooked to the frsh_init function and it is
85 * intented to initialize the protocol and its structures.
87 * @param[in] resource_id The network we are referring to (a protocol
88 * could be able to handle several networks at the same time)
91 * 0 if there are no errors \n
92 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
93 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
94 * FNA_ERR_ALREADY_INITIALIZED:
95 * if the function has already been called before (with success) \n
98 int frescan_fna_init(const frsh_resource_id_t resource_id)
101 frescan_init_params_t init_params;
103 init_params.net = resource_id - FRESCAN_BWRES_FNA_NET_BASE;
104 init_params.node = FRESCAN_BWRES_FNA_LOCAL_NODE;
105 init_params.tx_fp_max_prio = FRESCAN_BWRES_TX_FP_MX_PRIO;
106 init_params.rx_num_of_channels = FRESCAN_BWRES_RX_NUM_CHANNELS;
107 init_params.rx_channel_max_prio = FRESCAN_BWRES_RX_CHAN_MX_PRIO;
109 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
110 "Initializing FRESCAN FNA node%u\n", init_params.node);
112 ret = frescan_init(&init_params);
114 FRESCAN_ERROR ("could not init FRESCAN\n");
118 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
120 ret = frescan_bwres_init(init_params.net);
122 FRESCAN_ERROR ("could not init BWRES\n");
129 ///////////////////////////////////////////////////////////////////
131 ///////////////////////////////////////////////////////////////////
133 int frescan_fna_group_change_mode_sync
134 (const frsh_resource_id_t resource_id,
135 const frsh_contracts_group_t *contracts_to_neg,
136 const frsh_contracts_group_t *contracts_to_reneg,
137 const fna_vres_group_t *vres_to_reneg,
138 const fna_vres_group_t *vres_to_cancel,
139 fna_vres_group_t *new_vres)
143 frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
145 // convert fna_vres to ss
146 if (vres_to_reneg == NULL) {
147 ss_to_reneg.size = 0;
149 ss_to_reneg.size = vres_to_reneg->size;
150 if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
151 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
155 for(i=0; i<ss_to_reneg.size; i++) {
157 (frescan_ss_t)vres_to_reneg->vres[i];
161 if (vres_to_cancel == NULL) {
162 ss_to_cancel.size = 0;
164 ss_to_cancel.size = vres_to_cancel->size;
165 if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
166 FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
170 for(i=0; i<ss_to_cancel.size; i++) {
172 (frescan_ss_t)vres_to_cancel->vres[i];
176 if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
177 FRESCAN_ERROR("new_vres is NULL\n");
182 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
183 "calling frescan_bwres_group_change_mode_sync\n");
185 ret = frescan_bwres_group_change_mode_sync
186 ((frescan_network_t)resource_id,
193 if (ret != 0) return -1;
195 if (accepted == false) {
196 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
197 return -1; // TODO: change to constant FNA_REJECTED
200 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
201 // convert new ss to fna_vres
202 if (contracts_to_neg != NULL) {
203 new_vres->size = ss_new.size;
204 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
205 "new_vres->size:%d\n", new_vres->size);
206 for(i=0; i<new_vres->size; i++) {
207 new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
208 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
209 "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
217 * frescan_fna_contract_negotiate()
219 * The operation negotiates a contract and if accepted it will return
220 * a fna_vres_id_t. It will also check that the given contract_id is unique
221 * within the network.
223 * If the on-line admission test is enabled, it determines whether the
224 * contract can be admitted or not based on the current contracts
225 * established in the network. Then it creates the vres and
226 * recalculates all necessary parameters for the contracts already
227 * present in the system.
229 * This is a potentially blocking operation, it returns when the
230 * system has either rejected the contract, or admitted it and made it
233 * @param[in] resource_id The network we are referring to (a protocol
234 * could be able to handle several networks at the same time)
235 * @param[in] contract The contract parameters to negotiate
236 * @param[out] vres The internal virtual resource id
239 * 0 if there are no errors (in this case it also means contract accepted) \n
240 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
241 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
242 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
243 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
244 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
245 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
246 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
249 int frescan_fna_contract_negotiate
250 (const frsh_resource_id_t resource_id,
251 const frsh_contract_t *contract,
255 frsh_contracts_group_t contracts_to_neg;
256 fna_vres_group_t new_vres;
258 contracts_to_neg.size = 1;
259 contracts_to_neg.contracts[0] = *contract;
261 ret = frescan_fna_group_change_mode_sync
262 (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
263 if (ret != 0) return ret;
265 *vres = new_vres.vres[0];
270 * frescan_fna_contract_renegotiate_sync()
272 * The operation renegotiates a contract for an existing vres. If
273 * the on-line admission test is enabled it determines whether the
274 * contract can be admitted or not based on the current contracts
275 * established in the system. If it cannot be admitted, the old
276 * contract remains in effect and an error is returned. If it can be
277 * admitted, it recalculates all necessary parameters for the
278 * contracts already present in the system and returns zero. This is a
279 * potentially blocking operation; it returns when the system has
280 * either rejected the new contract, or admitted it and made it
283 * @param[in] resource_id The network we are referring to (a protocol
284 * could be able to handle several networks at the same time)
285 * @param[in] vres The internal virtual resource id to renegotiate
286 * @param[in] new_contract The new contract
289 * 0 if there are no errors (in this case it also means contract accepted) \n
290 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
291 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
292 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
293 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
294 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
295 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
296 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
299 int frescan_fna_contract_renegotiate_sync
300 (const frsh_resource_id_t resource_id,
301 const fna_vres_id_t vres,
302 const frsh_contract_t *new_contract)
304 frsh_contracts_group_t contracts_to_reneg;
305 fna_vres_group_t vres_to_reneg;
307 contracts_to_reneg.size = 1;
308 contracts_to_reneg.contracts[0] = *new_contract;
309 vres_to_reneg.size = 1;
310 vres_to_reneg.vres[0] = vres;
312 return frescan_fna_group_change_mode_sync
313 (resource_id, NULL, &contracts_to_reneg,
314 &vres_to_reneg, NULL, NULL);
318 * frescan_fna_contract_renegotiate_async()
320 * The operation enqueues a renegotiate operation for an existing
321 * vres, and returns immediately. The renegotiate operation is
322 * performed asynchronously, as soon as it is practical; meanwhile the
323 * system operation will continue normally. When the renegotiation is
324 * made, if the on-line admission test is enabled it determines
325 * whether the contract can be admitted or not based on the current
326 * contracts established in the system. If it cannot be admitted, the
327 * old contract remains in effect. If it can be admitted, it
328 * recalculates all necessary parameters for the contracts already
329 * present in the system.
331 * When the operation is completed, notification is made to the
332 * caller, if requested, via a signal. The status of the operation (in
333 * progress, admitted, rejected) can be checked with the
334 * frsh_vres_get_renegotiation_status() operation. The argument
335 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
336 * signal value and in this case signal_info is to be sent with the signal.
338 * @param[in] resource_id The network we are referring to (a protocol
339 * could be able to handle several networks at the same time)
340 * @param[in] vres The internal virtual resource id to renegotiate
341 * @param[in] new_contract The new contract
342 * @param[in] signal_to_notify Signal number to use to notify vres of
343 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
344 * @param[in] signal_info: Associated info that will come with the signal.
345 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
348 * 0 if there are no errors \n
349 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
350 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
351 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
352 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
353 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
354 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
355 * NULL nor a valid POSIX signal \n
358 int frescan_fna_contract_renegotiate_async
359 (const frsh_resource_id_t resource_id,
360 const fna_vres_id_t vres,
361 const frsh_contract_t *new_contract,
362 frsh_signal_t signal_to_notify,
363 frsh_signal_info_t signal_info)
365 FRESCAN_ERROR("not implemented\n");
370 * frescan_fna_vres_get_renegotiation_status()
372 * The operation reports on the status of the last renegotiation
373 * operation enqueued for the specified vres. It is callable even
374 * after notification of the completion of such operation, if
377 * If the vres is not and has not been involved in any of the
378 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
379 * operations, the status returned is FNA_NOT_REQUESTED
381 * @param[in] resource_id The network we are referring to (a protocol
382 * could be able to handle several networks at the same time)
383 * @param[in] vres The internal virtual resource id we want the status from
384 * @param[in] renegotiation_status The status of the last renegotiation on
385 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
386 * FRSH_RS_NOT_REQUESTED)
389 * 0 if there are no errors \n
390 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
391 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
392 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
393 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
394 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
397 int frescan_fna_vres_get_renegotiation_status
398 (const frsh_resource_id_t resource_id,
399 const fna_vres_id_t vres,
400 frsh_renegotiation_status_t *renegotiation_status)
402 FRESCAN_ERROR("not implemented\n");
407 * frescan_fna_vres_destroy()
409 * The operation eliminates the specified vres
410 * and recalculates all necessary parameters for the contracts
411 * remaining in the system. This is a potentially blocking operation;
412 * it returns when the system has made the changes effective.
414 * @param[in] resource_id The network we are referring to (a protocol
415 * could be able to handle several networks at the same time)
416 * @param[in] vres The internal virtual resource id to destroy
419 * 0 if there are no errors \n
420 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
421 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
422 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
423 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
424 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
427 int frescan_fna_vres_destroy
428 (const frsh_resource_id_t resource_id,
429 const fna_vres_id_t vres)
431 fna_vres_group_t vres_to_cancel;
433 vres_to_cancel.size = 1;
434 vres_to_cancel.vres[0] = vres;
436 return frescan_fna_group_change_mode_sync
437 (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
441 * frescan_fna_vres_get_contract()
443 * This operation stores the contract parameters currently associated
444 * with the specified vres in the variable pointed to by
445 * contract. It returns an error if the vres_id is not recognised.
447 * @param[in] resource_id The network we are referring to (a protocol
448 * could be able to handle several networks at the same time)
449 * @param[in] vres The internal virtual resource id
450 * @param[out] contract The contract parameters that we want
453 * 0 if there are no errors \n
454 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
455 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
456 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
457 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
458 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
461 int frescan_fna_vres_get_contract
462 (const frsh_resource_id_t resource_id,
463 const fna_vres_id_t vres,
464 frsh_contract_t *contract)
466 FRESCAN_ERROR("not implemented\n");
471 * frescan_fna_vres_get_usage()
473 * This function gets the execution time spent by all messages that have been
474 * sent through the specified vres.
476 * @param[in] resource_id The network we are referring to (a protocol
477 * could be able to handle several networks at the same time)
478 * @param[in] vres The internal virtual resource id
479 * @param[out] usage Execution time spent by this vres
482 * 0 if there are no errors \n
483 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
484 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
485 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
486 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
487 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
490 int frescan_fna_vres_get_usage
491 (const frsh_resource_id_t resource_id,
492 const fna_vres_id_t vres,
493 struct timespec *usage)
495 FRESCAN_ERROR("not implemented\n");
500 * frescan_fna_vres_get_remaining_budget()
502 * This function stores in the variable pointed to by budget the
503 * remaining execution-time budget associated with the specified
504 * vres in the present period.
506 * @param[in] resource_id The network we are referring to (a protocol
507 * could be able to handle several networks at the same time)
508 * @param[in] vres The internal virtual resource id
509 * @param[out] remaining_budget The remaining budget for this period
512 * 0 if there are no errors \n
513 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
514 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
515 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
516 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
517 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
520 int frescan_fna_vres_get_remaining_budget
521 (const frsh_resource_id_t resource_id,
522 const fna_vres_id_t vres,
523 struct timespec *remaining_budget)
525 FRESCAN_ERROR("not implemented\n");
530 * frescan_fna_vres_get_budget_and_period()
532 * This function gets the budget and period associated with the specified vres
533 * for each period. If one of these pointers is NULL, the corresponding
534 * information is not stored.
536 * @param[in] resource_id The network we are referring to (a protocol
537 * could be able to handle several networks at the same time)
538 * @param[in] vres The internal virtual resource id
539 * @param[out] budget The budget associated to vres
540 * @param[out] period The period associated to vres
543 * 0 if there are no errors \n
544 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
545 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
546 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
547 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
548 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
551 int frescan_fna_vres_get_budget_and_period
552 (const frsh_resource_id_t resource_id,
553 const fna_vres_id_t vres,
554 struct timespec *budget,
555 struct timespec *period)
558 frescan_server_params_t server_params;
560 ret = frescan_servers_get_data((frescan_network_t)resource_id,
563 if (ret != 0) return ret;
565 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
566 server_params.budget);
568 *period = server_params.period;
570 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
571 "budget(%d packets %ld us\n",
572 server_params.budget, frsh_rel_time_to_usec(*budget));
579 ///////////////////////////////////////////////////////////////////
580 // SPARE CAPACITY FUNCIONS
581 ///////////////////////////////////////////////////////////////////
584 * @defgroup fnaspare FNA Spare Capacity
587 * The following functions are used to get spare capacity data
593 * frescan_fna_resource_get_capacity()
595 * This operation gets the spare capacity currently assigned to a importance
596 * level. If we divide this value by UINT32_MAX we will get the network
597 * utilization associated to the spare capacity of a importance level.
599 * The following is typically in stdint.h: \n
600 * - typedef unsigned int uint32_t; \n
601 * - # define UINT32_MAX (4294967295U) \n
603 * @param[in] resource_id The network we are referring to (a protocol
604 * could be able to handle several networks at the same time)
605 * @param[in] importance The importance we want the capacity of
606 * @param[out] capacity The spare capacity for that importance level
609 * 0 if there are no errors \n
610 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
611 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
612 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
613 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
616 int frescan_fna_resource_get_capacity
617 (const frsh_resource_id_t resource_id,
618 const int importance,
621 FRESCAN_ERROR("not implemented\n");
626 * frescan_fna_resource_get_total_weight()
628 * This function gets the sum of the weight parameters for all vres in a
629 * network of an importance level.
631 * @param[in] resource_id The network we are referring to (a protocol
632 * could be able to handle several networks at the same time)
633 * @param[in] importance The importance we want the total weight of
634 * @param[out] total_weight The total weight for that importance level
637 * 0 if there are no errors \n
638 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
639 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
640 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
641 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
644 int frescan_fna_resource_get_total_weight
645 (const frsh_resource_id_t resource_id,
646 const int importance,
649 FRESCAN_ERROR("not implemented\n");
654 * frescan_fna_vres_decrease_capacity()
656 * This function allows to ask for less budget and period than what we
657 * received. The request must be compatible with the rest of contract
658 * parameters of the vres. If we want to recover the released capacity
659 * we will need to renegotiate.
661 * @param[in] resource_id The network we are referring to (a protocol
662 * could be able to handle several networks at the same time)
663 * @param[in] vres The internal virtual resource id
664 * @param[in] new_budget The new_budget
665 * @param[in] new_period The new Period
668 * 0 if there are no errors \n
669 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
670 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
671 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
672 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
673 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
674 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
678 int frescan_fna_vres_decrease_capacity
679 (const frsh_resource_id_t resource_id,
680 const fna_vres_id_t vres,
681 const struct timespec new_budget,
682 const struct timespec new_period)
684 FRESCAN_ERROR("not implemented\n");
688 ///////////////////////////////////////////////////////////////////
689 // SEND RECEIVE OPERATIONS
690 ///////////////////////////////////////////////////////////////////
693 * frescan_fna_send_sync()
695 * Similar to previous function but now the sending thread gets blocked
696 * until the message is already sent to the network.
698 * @param[in] endpoint The send endpoint we are sending through. It must
699 * be bound to a virtual resource (resource_id is in the endpoint).
700 * @param[in] msg The message we want to send
701 * @param[in] size The size in bytes of the message
704 * 0 if there are no errors \n
705 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
706 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
707 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
708 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
709 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
710 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
711 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
712 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
715 int frescan_fna_send_sync
716 (const fna_endpoint_data_t *endpoint,
720 FRESCAN_ERROR("not implemented\n");
725 * frescan_fna_send_async()
727 * This operation sends a message stored in msg and of length size
728 * through the given send endpoint. The operation is non-blocking and
729 * returns immediately.
731 * @param[in] endpoint The send endpoint we are sending through. It must
732 * be bound to a virtual resource (resource_id is in the endpoint).
733 * @param[in] msg The message we want to send
734 * @param[in] size The size in bytes of the message
737 * 0 if there are no errors \n
738 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
739 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
740 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
741 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
742 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
743 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
744 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
745 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
748 int frescan_fna_send_async
749 (const fna_endpoint_data_t *endpoint,
754 frescan_send_params_t params;
756 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
757 "net:%u dest:%u chan:%u size:%u ss:%u\n",
758 endpoint->resource_id, endpoint->destination,
759 endpoint->stream_id, size, endpoint->vres);
761 params.net = (frescan_network_t)endpoint->resource_id;
762 params.to = (frescan_node_t)endpoint->destination;
763 params.channel = (frescan_channel_t)endpoint->stream_id;
764 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
765 params.ss = endpoint->vres;
767 ret = frescan_send(¶ms, (uint8_t *)msg, size);
769 FRESCAN_ERROR ("could not send message\n");
777 * frescan_fna_receive_sync()
779 * This operation is used to receive messages from the network with a
780 * blocking behavior (if there are no messages this operation blocks
781 * the calling thread).
783 * When a message is available, it is copied to buffer (up to its size).
784 * The number of bytes copied is returned in received_bytes. The rest
785 * of the bytes of that message will be lost or not depending on the
786 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
788 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
789 * too small for the message received. In this case the message is
792 * Messages arriving at a receiver buffer that is full will be handled
793 * according to the queueing policy of the endpoint (overwrite oldest,
796 * @param[in] endpoint The receive endpoint we are receiving from.
797 * (resource_id is in the endpoint).
798 * @param[out] buffer Buffer for storing the received message
799 * @param[in] buffer_size The size in bytes of this buffer
800 * @param[out] received_bytes The actual number of received bytes
801 * @param[out] from Address of the sender node
804 * 0 if there are no errors \n
805 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
806 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
807 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
808 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
809 * FNA_ERR_NO_SPACE: if the message size is bigger than the
810 * provided buffer. \n
813 int frescan_fna_receive_sync
814 (const fna_endpoint_data_t *endpoint,
816 const size_t buffer_size,
817 size_t *received_bytes,
818 frsh_network_address_t *from)
821 frescan_recv_params_t params;
822 frescan_node_t frescan_from;
825 params.net = (frescan_network_t)endpoint->resource_id;
826 params.channel = (frescan_channel_t)endpoint->stream_id;
827 params.flags = FRESCAN_SYNC;
829 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
830 "net:%u chan:%u size:%u\n",
831 endpoint->resource_id, endpoint->stream_id, buffer_size);
833 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
834 received_bytes, &frescan_from, &prio);
837 FRESCAN_ERROR ("error while receiving message");
841 *from = (frsh_network_address_t)frescan_from;
843 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
844 "msg received, from:%u bytes:%u prio:%u\n",
845 *from, *received_bytes, prio);
851 * frescan_fna_receive_async()
853 * This operation is similar to the previous one but it works in a non
854 * blocking (asynchronous) fashion. If no message is available it
855 * returns with error FNA_NO_MESSAGE.
857 * @param[in] endpoint The receive endpoint we are receiving from.
858 * (resource_id is in the endpoint).
859 * @param[out] buffer Buffer for storing the received message
860 * @param[in] buffer_size The size in bytes of this buffer
861 * @param[out] received_bytes The actual number of received bytes
862 * @param[out] from Address of the sender node
865 * 0 if there are no errors \n
866 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
867 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
868 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
869 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
870 * FNA_ERR_NO_SPACE: if the message size is bigger than the
871 * provided buffer. \n
872 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
875 int frescan_fna_receive_async
876 (const fna_endpoint_data_t *endpoint,
878 const size_t buffer_size,
879 size_t *received_bytes,
880 frsh_network_address_t *from)
882 FRESCAN_ERROR("not implemented\n");
887 * frescan_fna_send_endpoint_get_status()
889 * This function tells the number of messages still pending in the
890 * endpoint queue, whether the network is up or down with some
891 * optional information which is protocol_dependent.
893 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
894 * @param[out] number_of_pending_messages The number of pending messages
895 * @param[out] network_status How is the network (up, down..)
896 * @param[out] protocol_status Protocol dependent status info
899 * 0 if there are no errors \n
900 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
901 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
902 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
903 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
906 int frescan_fna_send_endpoint_get_status
907 (const fna_endpoint_data_t *endpoint,
908 int *number_of_pending_messages,
909 frsh_endpoint_network_status_t *network_status,
910 frsh_protocol_status_t *protocol_status)
912 FRESCAN_ERROR("not implemented\n");
917 * frescan_fna_receive_endpoint_created()
919 * This operation is a called from frsh_receive_endpoint_create with a
920 * receive_endpoint structure already filled.
922 * Receiving endpoints are not bound to any network vres, this is
923 * because don't originate any traffic.
925 * @param[in] endpoint the endpoint object.
928 * 0 if there are no errors \n
929 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
930 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
931 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
932 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
934 int frescan_fna_receive_endpoint_created
935 (fna_endpoint_data_t *endpoint)
937 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
942 * frescan_fna_receive_endpoint_get_pending_messages
944 * This function tells the number of messages still pending in the
945 * endpoint queue, whether the network is up or down and some optional
946 * information which is protocol dependent.
948 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
949 * @param[out] number_of_pending_messages The number of pending messages
950 * @param[out] network_status How is the network (up, down..)
951 * @param[out] protocol_status Protocol dependent status info
954 * 0 if there are no errors \n
955 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
956 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
957 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
958 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
961 int frescan_fna_receive_endpoint_get_status
962 (const fna_endpoint_data_t *endpoint,
963 int *number_of_pending_messages,
964 frsh_endpoint_network_status_t *network_status,
965 frsh_protocol_status_t *protocol_status)
967 FRESCAN_ERROR("not implemented\n");
971 //////////////////////////////////////////////////////////////////////
972 // NETWORK CONFIGURATION FUNCTIONS
973 //////////////////////////////////////////////////////////////////////
976 * frescan_fna_network_get_max_message_size()
978 * This operation gives the maximum number of bytes that can be sent
979 * at a time through the send function when using the network designated by
980 * 'resource_id' and sending it to 'destination'.
982 * If the application needs to send bigger messages it will have to
985 * Some protocols, like IP, are capable of sending large messages
986 * (and use fragmentation internally) but other protocols don't.
988 * @param[in] resource_id The network we want the tx time from.
989 * @param[in] destination The destination address
990 * @param[out] max_size The maximum number of bytes for each message
993 * 0 if there are no errors \n
994 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
995 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
996 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
997 * a network accessible from the current processing node \n
998 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
1002 int frescan_fna_network_get_max_message_size
1003 (const frsh_resource_id_t resource_id,
1004 const frsh_network_address_t destination,
1007 FRESCAN_ERROR("not implemented\n");
1012 * frescan_fna_network_bytes_to_budget()
1014 * This operation converts a number of bytes into a temporal budget for
1015 * a specific network. Network overheads are not included here but are
1016 * considered internally when negotiating a specific contract.
1018 * @param[in] resource_id The network
1019 * @param[in] nbytes Number of bytes
1020 * @param[out] budget The network budget for nbytes
1023 * 0 if there are no errors \n
1024 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1025 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1026 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1027 * a network accessible from the current processing node \n
1028 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
1032 int frescan_fna_network_bytes_to_budget
1033 (const frsh_resource_id_t resource_id,
1034 const size_t nbytes,
1035 frsh_rel_time_t *budget)
1037 int number_of_packets;
1039 if (budget == NULL || nbytes < 0) {
1043 // number of FRESCAN frames (8 bytes)
1044 number_of_packets = (int) ceil((double)nbytes / 8.0);
1045 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
1048 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
1049 "bytes: %d -> budget: %ld us\n",
1050 nbytes, frsh_rel_time_to_usec(*budget));
1056 * frescan_fna_network_budget_to_bytes()
1058 * This operation converts a temporal budget into a number of bytes for
1059 * a specific network. Network overheads are not included.
1061 * @param[in] resource_id The network
1062 * @param[in] budget The network budget for nbytes
1063 * @param[out] nbytes Number of bytes
1066 * 0 if there are no errors \n
1067 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1068 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1069 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1070 * a network accessible from the current processing node \n
1071 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
1072 * an invalid time value \n
1075 int frescan_fna_network_budget_to_bytes
1076 (const frsh_resource_id_t resource_id,
1077 const frsh_rel_time_t *budget,
1080 int number_of_packets;
1082 if (budget == NULL || nbytes == NULL) {
1086 number_of_packets = frsh_rel_time_to_usec(*budget) /
1087 FRESCAN_FRAME_TX_TIME_US;
1089 *nbytes = number_of_packets * 8;
1095 * frescan_fna_network_get_min_eff_budget()
1097 * This operation gets the minimum effective budget for a network. Each message
1098 * consumes a contracted budget in "chunks" (i.e: packets) that we call
1099 * minimum effective budget.
1101 * A negotiated contract, for N bytes in a period T, means that there is a
1102 * virtual resource that reserves for the user:
1104 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1106 * Note that if the user decides not to send these N bytes at once but, say,
1107 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1108 * budget will become exhausted before sending all the bytes.
1110 * @param[in] resource_id The network
1111 * @param[out] budget The network budget
1114 * 0 if there are no errors \n
1115 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1116 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1117 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1118 * a network accessible from the current processing node \n
1119 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1122 int frescan_fna_network_get_min_eff_budget
1123 (const frsh_resource_id_t resource_id,
1124 struct timespec *budget)
1126 if (budget == NULL) {
1130 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1135 // GLOBAL variable to install the network protocol in FRESCOR
1137 fna_operations_t frescan_fna_operations = {
1138 #ifdef CONFIG_FNA_FRESCAN_CONNECTED
1139 .fna_init = frescan_fna_init,
1140 .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
1141 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1142 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1143 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1144 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1145 .fna_vres_destroy = frescan_fna_vres_destroy,
1146 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1147 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1148 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1149 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1150 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1151 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1152 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1153 .fna_send_sync = frescan_fna_send_sync,
1154 .fna_send_async = frescan_fna_send_async,
1155 .fna_receive_sync = frescan_fna_receive_sync,
1156 .fna_receive_async = frescan_fna_receive_async,
1157 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1158 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1159 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1161 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1162 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1163 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1164 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget