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 "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
72 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
74 //////////////////////////////////////////////////////////////////////
76 //////////////////////////////////////////////////////////////////////
81 * This function will be hooked to the frsh_init function and it is
82 * intented to initialize the protocol and its structures.
84 * @param[in] resource_id The network we are referring to (a protocol
85 * could be able to handle several networks at the same time)
88 * 0 if there are no errors \n
89 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
90 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
91 * FNA_ERR_ALREADY_INITIALIZED:
92 * if the function has already been called before (with success) \n
95 int frescan_fna_init(const frsh_resource_id_t resource_id)
98 frescan_init_params_t init_params;
100 // TODO: resource_id must be relative or sth
101 // TODO: init_params must be configurable
102 init_params.net = (frescan_network_t)resource_id;
103 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
104 init_params.tx_fp_max_prio = 10;
105 init_params.rx_num_of_channels = 10;
106 init_params.rx_channel_max_prio = NULL;
108 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
110 ret = frescan_init(&init_params);
111 if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
113 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
115 ret = frescan_bwres_init(init_params.net);
116 if (ret != 0) FRESCAN_ERROR ("could not init BWRES");
121 ///////////////////////////////////////////////////////////////////
123 ///////////////////////////////////////////////////////////////////
126 * frescan_fna_contract_negotiate()
128 * The operation negotiates a contract and if accepted it will return
129 * a fna_vres_id_t. It will also check that the given contract_id is unique
130 * within the network.
132 * If the on-line admission test is enabled, it determines whether the
133 * contract can be admitted or not based on the current contracts
134 * established in the network. Then it creates the vres and
135 * recalculates all necessary parameters for the contracts already
136 * present in the system.
138 * This is a potentially blocking operation, it returns when the
139 * system has either rejected the contract, or admitted it and made it
142 * @param[in] resource_id The network we are referring to (a protocol
143 * could be able to handle several networks at the same time)
144 * @param[in] contract The contract parameters to negotiate
145 * @param[out] vres The internal virtual resource id
148 * 0 if there are no errors (in this case it also means contract accepted) \n
149 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
150 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
151 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
152 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
153 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
154 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
155 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
158 int frescan_fna_contract_negotiate
159 (const frsh_resource_id_t resource_id,
160 const frsh_contract_t *contract,
167 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
168 ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
172 if (ret != 0) return -1;
174 if (accepted == true) {
175 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
176 *vres = (fna_vres_id_t)ss;
179 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
180 return -1; // TODO: change to constant FNA_REJECTED
185 * frescan_fna_contract_renegotiate_sync()
187 * The operation renegotiates a contract for an existing vres. If
188 * the on-line admission test is enabled it determines whether the
189 * contract can be admitted or not based on the current contracts
190 * established in the system. If it cannot be admitted, the old
191 * contract remains in effect and an error is returned. If it can be
192 * admitted, it recalculates all necessary parameters for the
193 * contracts already present in the system and returns zero. This is a
194 * potentially blocking operation; it returns when the system has
195 * either rejected the new contract, or admitted it and made it
198 * @param[in] resource_id The network we are referring to (a protocol
199 * could be able to handle several networks at the same time)
200 * @param[in] vres The internal virtual resource id to renegotiate
201 * @param[in] new_contract The new contract
204 * 0 if there are no errors (in this case it also means contract accepted) \n
205 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
206 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
207 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
208 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
209 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
210 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
211 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
214 int frescan_fna_contract_renegotiate_sync
215 (const frsh_resource_id_t resource_id,
216 const fna_vres_id_t vres,
217 const frsh_contract_t *new_contract)
219 FRESCAN_ERROR("not implemented\n");
224 * frescan_fna_contract_renegotiate_async()
226 * The operation enqueues a renegotiate operation for an existing
227 * vres, and returns immediately. The renegotiate operation is
228 * performed asynchronously, as soon as it is practical; meanwhile the
229 * system operation will continue normally. When the renegotiation is
230 * made, if the on-line admission test is enabled it determines
231 * whether the contract can be admitted or not based on the current
232 * contracts established in the system. If it cannot be admitted, the
233 * old contract remains in effect. If it can be admitted, it
234 * recalculates all necessary parameters for the contracts already
235 * present in the system.
237 * When the operation is completed, notification is made to the
238 * caller, if requested, via a signal. The status of the operation (in
239 * progress, admitted, rejected) can be checked with the
240 * frsh_vres_get_renegotiation_status() operation. The argument
241 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
242 * signal value and in this case signal_info is to be sent with the signal.
244 * @param[in] resource_id The network we are referring to (a protocol
245 * could be able to handle several networks at the same time)
246 * @param[in] vres The internal virtual resource id to renegotiate
247 * @param[in] new_contract The new contract
248 * @param[in] signal_to_notify Signal number to use to notify vres of
249 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
250 * @param[in] signal_info: Associated info that will come with the signal.
251 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
254 * 0 if there are no errors \n
255 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
256 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
257 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
258 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
259 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
260 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
261 * NULL nor a valid POSIX signal \n
264 int frescan_fna_contract_renegotiate_async
265 (const frsh_resource_id_t resource_id,
266 const fna_vres_id_t vres,
267 const frsh_contract_t *new_contract,
268 frsh_signal_t signal_to_notify,
269 frsh_signal_info_t signal_info)
271 FRESCAN_ERROR("not implemented\n");
276 * frescan_fna_vres_get_renegotiation_status()
278 * The operation reports on the status of the last renegotiation
279 * operation enqueued for the specified vres. It is callable even
280 * after notification of the completion of such operation, if
283 * If the vres is not and has not been involved in any of the
284 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
285 * operations, the status returned is FNA_NOT_REQUESTED
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 we want the status from
290 * @param[in] renegotiation_status The status of the last renegotiation on
291 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
292 * FRSH_RS_NOT_REQUESTED)
295 * 0 if there are no errors \n
296 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
297 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \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_vres_get_renegotiation_status
304 (const frsh_resource_id_t resource_id,
305 const fna_vres_id_t vres,
306 frsh_renegotiation_status_t *renegotiation_status)
308 FRESCAN_ERROR("not implemented\n");
313 * frescan_fna_vres_destroy()
315 * The operation eliminates the specified vres
316 * and recalculates all necessary parameters for the contracts
317 * remaining in the system. This is a potentially blocking operation;
318 * it returns when the system has made the changes effective.
320 * @param[in] resource_id The network we are referring to (a protocol
321 * could be able to handle several networks at the same time)
322 * @param[in] vres The internal virtual resource id to destroy
325 * 0 if there are no errors \n
326 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
327 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
328 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
329 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
330 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
333 int frescan_fna_vres_destroy
334 (const frsh_resource_id_t resource_id,
335 const fna_vres_id_t vres)
337 FRESCAN_ERROR("not implemented\n");
342 * frescan_fna_vres_get_contract()
344 * This operation stores the contract parameters currently associated
345 * with the specified vres in the variable pointed to by
346 * contract. It returns an error if the vres_id is not recognised.
348 * @param[in] resource_id The network we are referring to (a protocol
349 * could be able to handle several networks at the same time)
350 * @param[in] vres The internal virtual resource id
351 * @param[out] contract The contract parameters that we want
354 * 0 if there are no errors \n
355 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
356 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
357 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
358 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
359 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
362 int frescan_fna_vres_get_contract
363 (const frsh_resource_id_t resource_id,
364 const fna_vres_id_t vres,
365 frsh_contract_t *contract)
367 FRESCAN_ERROR("not implemented\n");
372 * frescan_fna_vres_get_usage()
374 * This function gets the execution time spent by all messages that have been
375 * sent through the specified vres.
377 * @param[in] resource_id The network we are referring to (a protocol
378 * could be able to handle several networks at the same time)
379 * @param[in] vres The internal virtual resource id
380 * @param[out] usage Execution time spent by this vres
383 * 0 if there are no errors \n
384 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
385 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
386 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
387 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
388 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
391 int frescan_fna_vres_get_usage
392 (const frsh_resource_id_t resource_id,
393 const fna_vres_id_t vres,
394 struct timespec *usage)
396 FRESCAN_ERROR("not implemented\n");
401 * frescan_fna_vres_get_remaining_budget()
403 * This function stores in the variable pointed to by budget the
404 * remaining execution-time budget associated with the specified
405 * vres in the present period.
407 * @param[in] resource_id The network we are referring to (a protocol
408 * could be able to handle several networks at the same time)
409 * @param[in] vres The internal virtual resource id
410 * @param[out] remaining_budget The remaining budget for this period
413 * 0 if there are no errors \n
414 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
415 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
416 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
417 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
418 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
421 int frescan_fna_vres_get_remaining_budget
422 (const frsh_resource_id_t resource_id,
423 const fna_vres_id_t vres,
424 struct timespec *remaining_budget)
426 FRESCAN_ERROR("not implemented\n");
431 * frescan_fna_vres_get_budget_and_period()
433 * This function gets the budget and period associated with the specified vres
434 * for each period. If one of these pointers is NULL, the corresponding
435 * information is not stored.
437 * @param[in] resource_id The network we are referring to (a protocol
438 * could be able to handle several networks at the same time)
439 * @param[in] vres The internal virtual resource id
440 * @param[out] budget The budget associated to vres
441 * @param[out] period The period associated to vres
444 * 0 if there are no errors \n
445 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
446 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
447 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
448 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
449 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
452 int frescan_fna_vres_get_budget_and_period
453 (const frsh_resource_id_t resource_id,
454 const fna_vres_id_t vres,
455 struct timespec *budget,
456 struct timespec *period)
458 FRESCAN_ERROR("not implemented\n");
464 ///////////////////////////////////////////////////////////////////
465 // SPARE CAPACITY FUNCIONS
466 ///////////////////////////////////////////////////////////////////
469 * @defgroup fnaspare FNA Spare Capacity
472 * The following functions are used to get spare capacity data
478 * frescan_fna_resource_get_capacity()
480 * This operation gets the spare capacity currently assigned to a importance
481 * level. If we divide this value by UINT32_MAX we will get the network
482 * utilization associated to the spare capacity of a importance level.
484 * The following is typically in stdint.h: \n
485 * - typedef unsigned int uint32_t; \n
486 * - # define UINT32_MAX (4294967295U) \n
488 * @param[in] resource_id The network we are referring to (a protocol
489 * could be able to handle several networks at the same time)
490 * @param[in] importance The importance we want the capacity of
491 * @param[out] capacity The spare capacity for that importance level
494 * 0 if there are no errors \n
495 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
496 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
497 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
498 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
501 int frescan_fna_resource_get_capacity
502 (const frsh_resource_id_t resource_id,
503 const int importance,
506 FRESCAN_ERROR("not implemented\n");
511 * frescan_fna_resource_get_total_weight()
513 * This function gets the sum of the weight parameters for all vres in a
514 * network of an importance level.
516 * @param[in] resource_id The network we are referring to (a protocol
517 * could be able to handle several networks at the same time)
518 * @param[in] importance The importance we want the total weight of
519 * @param[out] total_weight The total weight for that importance level
522 * 0 if there are no errors \n
523 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
524 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
525 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
526 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
529 int frescan_fna_resource_get_total_weight
530 (const frsh_resource_id_t resource_id,
531 const int importance,
534 FRESCAN_ERROR("not implemented\n");
539 * frescan_fna_vres_decrease_capacity()
541 * This function allows to ask for less budget and period than what we
542 * received. The request must be compatible with the rest of contract
543 * parameters of the vres. If we want to recover the released capacity
544 * we will need to renegotiate.
546 * @param[in] resource_id The network we are referring to (a protocol
547 * could be able to handle several networks at the same time)
548 * @param[in] vres The internal virtual resource id
549 * @param[in] new_budget The new_budget
550 * @param[in] new_period The new Period
553 * 0 if there are no errors \n
554 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
555 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
556 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
557 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
558 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
559 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
563 int frescan_fna_vres_decrease_capacity
564 (const frsh_resource_id_t resource_id,
565 const fna_vres_id_t vres,
566 const struct timespec new_budget,
567 const struct timespec new_period)
569 FRESCAN_ERROR("not implemented\n");
573 ///////////////////////////////////////////////////////////////////
574 // SEND RECEIVE OPERATIONS
575 ///////////////////////////////////////////////////////////////////
578 * frescan_fna_send_sync()
580 * Similar to previous function but now the sending thread gets blocked
581 * until the message is already sent to the network.
583 * @param[in] endpoint The send endpoint we are sending through. It must
584 * be bound to a virtual resource (resource_id is in the endpoint).
585 * @param[in] msg The message we want to send
586 * @param[in] size The size in bytes of the message
589 * 0 if there are no errors \n
590 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
591 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
592 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
593 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
594 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
595 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
596 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
597 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
600 int frescan_fna_send_sync
601 (const fna_endpoint_data_t *endpoint,
605 FRESCAN_ERROR("not implemented\n");
610 * frescan_fna_send_async()
612 * This operation sends a message stored in msg and of length size
613 * through the given send endpoint. The operation is non-blocking and
614 * returns immediately.
616 * @param[in] endpoint The send endpoint we are sending through. It must
617 * be bound to a virtual resource (resource_id is in the endpoint).
618 * @param[in] msg The message we want to send
619 * @param[in] size The size in bytes of the message
622 * 0 if there are no errors \n
623 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
624 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
625 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
626 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
627 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
628 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
629 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
630 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
633 int frescan_fna_send_async
634 (const fna_endpoint_data_t *endpoint,
639 frescan_send_params_t params;
641 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
642 "net:%u dest:%u chan:%u size:%u ss:%u\n",
643 endpoint->resource_id, endpoint->destination,
644 endpoint->stream_id, size, endpoint->vres);
646 params.net = (frescan_network_t)endpoint->resource_id;
647 params.to = (frescan_node_t)endpoint->destination;
648 params.channel = (frescan_channel_t)endpoint->stream_id;
649 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
650 params.ss = endpoint->vres;
652 ret = frescan_send(¶ms, (uint8_t *)msg, size);
654 FRESCAN_ERROR ("could not send message\n");
662 * frescan_fna_receive_sync()
664 * This operation is used to receive messages from the network with a
665 * blocking behavior (if there are no messages this operation blocks
666 * the calling thread).
668 * When a message is available, it is copied to buffer (up to its size).
669 * The number of bytes copied is returned in received_bytes. The rest
670 * of the bytes of that message will be lost or not depending on the
671 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
673 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
674 * too small for the message received. In this case the message is
677 * Messages arriving at a receiver buffer that is full will be handled
678 * according to the queueing policy of the endpoint (overwrite oldest,
681 * @param[in] endpoint The receive endpoint we are receiving from.
682 * (resource_id is in the endpoint).
683 * @param[out] buffer Buffer for storing the received message
684 * @param[in] buffer_size The size in bytes of this buffer
685 * @param[out] received_bytes The actual number of received bytes
686 * @param[out] from Address of the sender node
689 * 0 if there are no errors \n
690 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
691 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
692 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
693 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
694 * FNA_ERR_NO_SPACE: if the message size is bigger than the
695 * provided buffer. \n
698 int frescan_fna_receive_sync
699 (const fna_endpoint_data_t *endpoint,
701 const size_t buffer_size,
702 size_t *received_bytes,
703 frsh_network_address_t *from)
706 frescan_recv_params_t params;
707 frescan_node_t frescan_from;
710 params.net = (frescan_network_t)endpoint->resource_id;
711 params.channel = (frescan_channel_t)endpoint->stream_id;
712 params.flags = FRESCAN_SYNC;
714 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
715 "net:%u chan:%u size:%u\n",
716 endpoint->resource_id, endpoint->stream_id, buffer_size);
718 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
719 received_bytes, &frescan_from, &prio);
722 FRESCAN_ERROR ("error while receiving message");
726 *from = (frsh_network_address_t)frescan_from;
728 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
729 "msg received, from:%u bytes:%u prio:%u\n",
730 *from, *received_bytes, prio);
736 * frescan_fna_receive_async()
738 * This operation is similar to the previous one but it works in a non
739 * blocking (asynchronous) fashion. If no message is available it
740 * returns with error FNA_NO_MESSAGE.
742 * @param[in] endpoint The receive endpoint we are receiving from.
743 * (resource_id is in the endpoint).
744 * @param[out] buffer Buffer for storing the received message
745 * @param[in] buffer_size The size in bytes of this buffer
746 * @param[out] received_bytes The actual number of received bytes
747 * @param[out] from Address of the sender node
750 * 0 if there are no errors \n
751 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
752 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
753 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
754 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
755 * FNA_ERR_NO_SPACE: if the message size is bigger than the
756 * provided buffer. \n
757 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
760 int frescan_fna_receive_async
761 (const fna_endpoint_data_t *endpoint,
763 const size_t buffer_size,
764 size_t *received_bytes,
765 frsh_network_address_t *from)
767 FRESCAN_ERROR("not implemented\n");
772 * frescan_fna_send_endpoint_get_status()
774 * This function tells the number of messages still pending in the
775 * endpoint queue, whether the network is up or down with some
776 * optional information which is protocol_dependent.
778 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
779 * @param[out] number_of_pending_messages The number of pending messages
780 * @param[out] network_status How is the network (up, down..)
781 * @param[out] protocol_status Protocol dependent status info
784 * 0 if there are no errors \n
785 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
786 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
787 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
788 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
791 int frescan_fna_send_endpoint_get_status
792 (const fna_endpoint_data_t *endpoint,
793 int *number_of_pending_messages,
794 frsh_endpoint_network_status_t *network_status,
795 frsh_protocol_status_t *protocol_status)
797 FRESCAN_ERROR("not implemented\n");
802 * frescan_fna_receive_endpoint_created()
804 * This operation is a called from frsh_receive_endpoint_create with a
805 * receive_endpoint structure already filled.
807 * Receiving endpoints are not bound to any network vres, this is
808 * because don't originate any traffic.
810 * @param[in] endpoint the endpoint object.
813 * 0 if there are no errors \n
814 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
815 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
816 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
817 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
819 int frescan_fna_receive_endpoint_created
820 (fna_endpoint_data_t *endpoint)
822 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
827 * frescan_fna_receive_endpoint_get_pending_messages
829 * This function tells the number of messages still pending in the
830 * endpoint queue, whether the network is up or down and some optional
831 * information which is protocol dependent.
833 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
834 * @param[out] number_of_pending_messages The number of pending messages
835 * @param[out] network_status How is the network (up, down..)
836 * @param[out] protocol_status Protocol dependent status info
839 * 0 if there are no errors \n
840 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
841 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
842 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
843 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
846 int frescan_fna_receive_endpoint_get_status
847 (const fna_endpoint_data_t *endpoint,
848 int *number_of_pending_messages,
849 frsh_endpoint_network_status_t *network_status,
850 frsh_protocol_status_t *protocol_status)
852 FRESCAN_ERROR("not implemented\n");
856 //////////////////////////////////////////////////////////////////////
857 // NETWORK CONFIGURATION FUNCTIONS
858 //////////////////////////////////////////////////////////////////////
861 * frescan_fna_network_get_max_message_size()
863 * This operation gives the maximum number of bytes that can be sent
864 * at a time through the send function when using the network designated by
865 * 'resource_id' and sending it to 'destination'.
867 * If the application needs to send bigger messages it will have to
870 * Some protocols, like IP, are capable of sending large messages
871 * (and use fragmentation internally) but other protocols don't.
873 * @param[in] resource_id The network we want the tx time from.
874 * @param[in] destination The destination address
875 * @param[out] max_size The maximum number of bytes for each message
878 * 0 if there are no errors \n
879 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
880 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
881 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
882 * a network accessible from the current processing node \n
883 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
887 int frescan_fna_network_get_max_message_size
888 (const frsh_resource_id_t resource_id,
889 const frsh_network_address_t destination,
892 FRESCAN_ERROR("not implemented\n");
897 * frescan_fna_network_bytes_to_budget()
899 * This operation converts a number of bytes into a temporal budget for
900 * a specific network. Network overheads are not included here but are
901 * considered internally when negotiating a specific contract.
903 * @param[in] resource_id The network
904 * @param[in] nbytes Number of bytes
905 * @param[out] budget The network budget for nbytes
908 * 0 if there are no errors \n
909 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
910 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
911 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
912 * a network accessible from the current processing node \n
913 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
917 int frescan_fna_network_bytes_to_budget
918 (const frsh_resource_id_t resource_id,
920 frsh_rel_time_t *budget)
922 int number_of_packets;
924 if (budget == NULL || nbytes < 0) {
928 // number of FRESCAN frames (8 bytes)
929 number_of_packets = (int) ceil((double)nbytes / 8.0);
930 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
933 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
934 "bytes: %d -> budget: %ld us\n",
935 nbytes, frsh_rel_time_to_usec(*budget));
941 * frescan_fna_network_budget_to_bytes()
943 * This operation converts a temporal budget into a number of bytes for
944 * a specific network. Network overheads are not included.
946 * @param[in] resource_id The network
947 * @param[in] budget The network budget for nbytes
948 * @param[out] nbytes Number of bytes
951 * 0 if there are no errors \n
952 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
953 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
954 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
955 * a network accessible from the current processing node \n
956 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
957 * an invalid time value \n
960 int frescan_fna_network_budget_to_bytes
961 (const frsh_resource_id_t resource_id,
962 const frsh_rel_time_t *budget,
965 int number_of_packets;
967 if (budget == NULL || nbytes == NULL) {
971 number_of_packets = frsh_rel_time_to_usec(*budget) /
972 FRESCAN_FRAME_TX_TIME_US;
974 *nbytes = number_of_packets * 8;
980 * frescan_fna_network_get_min_eff_budget()
982 * This operation gets the minimum effective budget for a network. Each message
983 * consumes a contracted budget in "chunks" (i.e: packets) that we call
984 * minimum effective budget.
986 * A negotiated contract, for N bytes in a period T, means that there is a
987 * virtual resource that reserves for the user:
989 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
991 * Note that if the user decides not to send these N bytes at once but, say,
992 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
993 * budget will become exhausted before sending all the bytes.
995 * @param[in] resource_id The network
996 * @param[out] budget The network budget
999 * 0 if there are no errors \n
1000 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1001 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1002 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1003 * a network accessible from the current processing node \n
1004 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1007 int frescan_fna_network_get_min_eff_budget
1008 (const frsh_resource_id_t resource_id,
1009 struct timespec *budget)
1011 if (budget == NULL) {
1015 *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1020 // GLOBAL variable to install the network protocol in FRESCOR
1022 fna_operations_t frescan_fna_operations = {
1023 .fna_init = frescan_fna_init,
1024 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1025 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1026 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1027 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1028 .fna_vres_destroy = frescan_fna_vres_destroy,
1029 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1030 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1031 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1032 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1033 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1034 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1035 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1036 .fna_send_sync = frescan_fna_send_sync,
1037 .fna_send_async = frescan_fna_send_async,
1038 .fna_receive_sync = frescan_fna_receive_sync,
1039 .fna_receive_async = frescan_fna_receive_async,
1040 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1041 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1042 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1043 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1044 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1045 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1046 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget