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 #include <math.h> /* ceil */
18 #include "frsh.h" /* frsh_resource_id_t, .. */
19 #include "frescan.h" /* frescan_init, ... */
20 #include "frescan_data.h" /* frescan_contract_t, ... */
21 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
22 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
25 #include "frescan_debug.h" /* DEBUG, ERROR */
27 //////////////////////////////////////////////////////////////////////
29 //////////////////////////////////////////////////////////////////////
34 * This function will be hooked to the frsh_init function and it is
35 * intented to initialize the protocol and its structures.
37 * @param[in] resource_id The network we are referring to (a protocol
38 * could be able to handle several networks at the same time)
41 * 0 if there are no errors \n
42 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
43 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
44 * FNA_ERR_ALREADY_INITIALIZED:
45 * if the function has already been called before (with success) \n
48 int frescan_fna_init(const frsh_resource_id_t resource_id)
51 frescan_init_params_t init_params;
53 // TODO: resource_id must be relative or sth
54 // TODO: init_params must be configurable
55 init_params.net = (frescan_network_t)resource_id;
56 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
57 init_params.tx_fp_max_prio = 10;
58 init_params.rx_num_of_channels = 10;
59 init_params.rx_channel_max_prio = NULL;
61 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
63 ret = frescan_init(&init_params);
64 if (ret != 0) ERROR ("could not init FRESCAN");
66 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
68 ret = frescan_bwres_init(init_params.net);
69 if (ret != 0) ERROR ("could not init BWRES");
74 ///////////////////////////////////////////////////////////////////
76 ///////////////////////////////////////////////////////////////////
79 * frescan_fna_contract_negotiate()
81 * The operation negotiates a contract and if accepted it will return
82 * a fna_vres_id_t. It will also check that the given contract_id is unique
85 * If the on-line admission test is enabled, it determines whether the
86 * contract can be admitted or not based on the current contracts
87 * established in the network. Then it creates the vres and
88 * recalculates all necessary parameters for the contracts already
89 * present in the system.
91 * This is a potentially blocking operation, it returns when the
92 * system has either rejected the contract, or admitted it and made it
95 * @param[in] resource_id The network we are referring to (a protocol
96 * could be able to handle several networks at the same time)
97 * @param[in] contract The contract parameters to negotiate
98 * @param[out] vres The internal virtual resource id
101 * 0 if there are no errors (in this case it also means contract accepted) \n
102 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
103 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
104 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
105 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
106 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
107 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
108 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
111 int frescan_fna_contract_negotiate
112 (const frsh_resource_id_t resource_id,
113 const frsh_contract_t *contract,
119 frescan_contract_t frescan_contract;
121 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
122 "frsh contract->frescan contract\n");
124 // NOTE: budget is stored as number of can frames in tv_sec
125 frescan_contract.min_values.budget = contract->budget_min.tv_sec;
126 frescan_contract.min_values.period = contract->period_max;
128 frescan_contract.max_values.budget = contract->budget_max.tv_sec;
129 frescan_contract.max_values.period = contract->period_min;
131 // TODO: put 0 if we want the sa module to assign the prios
132 frescan_contract.prio = contract->preemption_level;
134 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
135 ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
139 if (ret != 0) return -1;
141 if (accepted == true) {
142 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
143 *vres = (fna_vres_id_t)ss;
146 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
147 return -1; // TODO: change to constant FNA_REJECTED
152 * frescan_fna_contract_renegotiate_sync()
154 * The operation renegotiates a contract for an existing vres. If
155 * the on-line admission test is enabled it determines whether the
156 * contract can be admitted or not based on the current contracts
157 * established in the system. If it cannot be admitted, the old
158 * contract remains in effect and an error is returned. If it can be
159 * admitted, it recalculates all necessary parameters for the
160 * contracts already present in the system and returns zero. This is a
161 * potentially blocking operation; it returns when the system has
162 * either rejected the new contract, or admitted it and made it
165 * @param[in] resource_id The network we are referring to (a protocol
166 * could be able to handle several networks at the same time)
167 * @param[in] vres The internal virtual resource id to renegotiate
168 * @param[in] new_contract The new contract
171 * 0 if there are no errors (in this case it also means contract accepted) \n
172 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
173 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
174 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
175 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
176 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
177 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
178 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
181 int frescan_fna_contract_renegotiate_sync
182 (const frsh_resource_id_t resource_id,
183 const fna_vres_id_t vres,
184 const frsh_contract_t *new_contract)
186 ERROR("not implemented\n");
191 * frescan_fna_contract_renegotiate_async()
193 * The operation enqueues a renegotiate operation for an existing
194 * vres, and returns immediately. The renegotiate operation is
195 * performed asynchronously, as soon as it is practical; meanwhile the
196 * system operation will continue normally. When the renegotiation is
197 * made, if the on-line admission test is enabled it determines
198 * whether the contract can be admitted or not based on the current
199 * contracts established in the system. If it cannot be admitted, the
200 * old contract remains in effect. If it can be admitted, it
201 * recalculates all necessary parameters for the contracts already
202 * present in the system.
204 * When the operation is completed, notification is made to the
205 * caller, if requested, via a signal. The status of the operation (in
206 * progress, admitted, rejected) can be checked with the
207 * frsh_vres_get_renegotiation_status() operation. The argument
208 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
209 * signal value and in this case signal_info is to be sent with the signal.
211 * @param[in] resource_id The network we are referring to (a protocol
212 * could be able to handle several networks at the same time)
213 * @param[in] vres The internal virtual resource id to renegotiate
214 * @param[in] new_contract The new contract
215 * @param[in] signal_to_notify Signal number to use to notify vres of
216 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
217 * @param[in] signal_info: Associated info that will come with the signal.
218 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
221 * 0 if there are no errors \n
222 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
223 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
224 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
225 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
226 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
227 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
228 * NULL nor a valid POSIX signal \n
231 int frescan_fna_contract_renegotiate_async
232 (const frsh_resource_id_t resource_id,
233 const fna_vres_id_t vres,
234 const frsh_contract_t *new_contract,
235 frsh_signal_t signal_to_notify,
236 frsh_signal_info_t signal_info)
238 ERROR("not implemented\n");
243 * frescan_fna_vres_get_renegotiation_status()
245 * The operation reports on the status of the last renegotiation
246 * operation enqueued for the specified vres. It is callable even
247 * after notification of the completion of such operation, if
250 * If the vres is not and has not been involved in any of the
251 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
252 * operations, the status returned is FNA_NOT_REQUESTED
254 * @param[in] resource_id The network we are referring to (a protocol
255 * could be able to handle several networks at the same time)
256 * @param[in] vres The internal virtual resource id we want the status from
257 * @param[in] renegotiation_status The status of the last renegotiation on
258 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
259 * FRSH_RS_NOT_REQUESTED)
262 * 0 if there are no errors \n
263 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
264 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
265 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
266 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
267 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
270 int frescan_fna_vres_get_renegotiation_status
271 (const frsh_resource_id_t resource_id,
272 const fna_vres_id_t vres,
273 frsh_renegotiation_status_t *renegotiation_status)
275 ERROR("not implemented\n");
280 * frescan_fna_vres_destroy()
282 * The operation eliminates the specified vres
283 * and recalculates all necessary parameters for the contracts
284 * remaining in the system. This is a potentially blocking operation;
285 * it returns when the system has made the changes effective.
287 * @param[in] resource_id The network we are referring to (a protocol
288 * could be able to handle several networks at the same time)
289 * @param[in] vres The internal virtual resource id to destroy
292 * 0 if there are no errors \n
293 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
294 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
295 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
296 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
297 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
300 int frescan_fna_vres_destroy
301 (const frsh_resource_id_t resource_id,
302 const fna_vres_id_t vres)
304 ERROR("not implemented\n");
309 * frescan_fna_vres_get_contract()
311 * This operation stores the contract parameters currently associated
312 * with the specified vres in the variable pointed to by
313 * contract. It returns an error if the vres_id is not recognised.
315 * @param[in] resource_id The network we are referring to (a protocol
316 * could be able to handle several networks at the same time)
317 * @param[in] vres The internal virtual resource id
318 * @param[out] contract The contract parameters that we want
321 * 0 if there are no errors \n
322 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
323 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
324 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
325 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
326 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
329 int frescan_fna_vres_get_contract
330 (const frsh_resource_id_t resource_id,
331 const fna_vres_id_t vres,
332 frsh_contract_t *contract)
334 ERROR("not implemented\n");
339 * frescan_fna_vres_get_usage()
341 * This function gets the execution time spent by all messages that have been
342 * sent through the specified vres.
344 * @param[in] resource_id The network we are referring to (a protocol
345 * could be able to handle several networks at the same time)
346 * @param[in] vres The internal virtual resource id
347 * @param[out] usage Execution time spent by this vres
350 * 0 if there are no errors \n
351 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
352 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
353 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
354 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
355 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
358 int frescan_fna_vres_get_usage
359 (const frsh_resource_id_t resource_id,
360 const fna_vres_id_t vres,
361 struct timespec *usage)
363 ERROR("not implemented\n");
368 * frescan_fna_vres_get_remaining_budget()
370 * This function stores in the variable pointed to by budget the
371 * remaining execution-time budget associated with the specified
372 * vres in the present period.
374 * @param[in] resource_id The network we are referring to (a protocol
375 * could be able to handle several networks at the same time)
376 * @param[in] vres The internal virtual resource id
377 * @param[out] remaining_budget The remaining budget for this period
380 * 0 if there are no errors \n
381 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
382 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
383 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
384 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
385 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
388 int frescan_fna_vres_get_remaining_budget
389 (const frsh_resource_id_t resource_id,
390 const fna_vres_id_t vres,
391 struct timespec *remaining_budget)
393 ERROR("not implemented\n");
398 * frescan_fna_vres_get_budget_and_period()
400 * This function gets the budget and period associated with the specified vres
401 * for each period. If one of these pointers is NULL, the corresponding
402 * information is not stored.
404 * @param[in] resource_id The network we are referring to (a protocol
405 * could be able to handle several networks at the same time)
406 * @param[in] vres The internal virtual resource id
407 * @param[out] budget The budget associated to vres
408 * @param[out] period The period associated to vres
411 * 0 if there are no errors \n
412 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
413 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
414 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
415 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
416 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
419 int frescan_fna_vres_get_budget_and_period
420 (const frsh_resource_id_t resource_id,
421 const fna_vres_id_t vres,
422 struct timespec *budget,
423 struct timespec *period)
425 ERROR("not implemented\n");
431 ///////////////////////////////////////////////////////////////////
432 // SPARE CAPACITY FUNCIONS
433 ///////////////////////////////////////////////////////////////////
436 * @defgroup fnaspare FNA Spare Capacity
439 * The following functions are used to get spare capacity data
445 * frescan_fna_resource_get_capacity()
447 * This operation gets the spare capacity currently assigned to a importance
448 * level. If we divide this value by UINT32_MAX we will get the network
449 * utilization associated to the spare capacity of a importance level.
451 * The following is typically in stdint.h: \n
452 * - typedef unsigned int uint32_t; \n
453 * - # define UINT32_MAX (4294967295U) \n
455 * @param[in] resource_id The network we are referring to (a protocol
456 * could be able to handle several networks at the same time)
457 * @param[in] importance The importance we want the capacity of
458 * @param[out] capacity The spare capacity for that importance level
461 * 0 if there are no errors \n
462 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
463 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
464 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
465 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
468 int frescan_fna_resource_get_capacity
469 (const frsh_resource_id_t resource_id,
470 const int importance,
473 ERROR("not implemented\n");
478 * frescan_fna_resource_get_total_weight()
480 * This function gets the sum of the weight parameters for all vres in a
481 * network of an importance level.
483 * @param[in] resource_id The network we are referring to (a protocol
484 * could be able to handle several networks at the same time)
485 * @param[in] importance The importance we want the total weight of
486 * @param[out] total_weight The total weight for that importance level
489 * 0 if there are no errors \n
490 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
491 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
492 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
493 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
496 int frescan_fna_resource_get_total_weight
497 (const frsh_resource_id_t resource_id,
498 const int importance,
501 ERROR("not implemented\n");
506 * frescan_fna_vres_decrease_capacity()
508 * This function allows to ask for less budget and period than what we
509 * received. The request must be compatible with the rest of contract
510 * parameters of the vres. If we want to recover the released capacity
511 * we will need to renegotiate.
513 * @param[in] resource_id The network we are referring to (a protocol
514 * could be able to handle several networks at the same time)
515 * @param[in] vres The internal virtual resource id
516 * @param[in] new_budget The new_budget
517 * @param[in] new_period The new Period
520 * 0 if there are no errors \n
521 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
522 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
523 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
524 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
525 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
526 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
530 int frescan_fna_vres_decrease_capacity
531 (const frsh_resource_id_t resource_id,
532 const fna_vres_id_t vres,
533 const struct timespec new_budget,
534 const struct timespec new_period)
536 ERROR("not implemented\n");
540 ///////////////////////////////////////////////////////////////////
541 // SEND RECEIVE OPERATIONS
542 ///////////////////////////////////////////////////////////////////
545 * frescan_fna_send_sync()
547 * Similar to previous function but now the sending thread gets blocked
548 * until the message is already sent to the network.
550 * @param[in] endpoint The send endpoint we are sending through. It must
551 * be bound to a virtual resource (resource_id is in the endpoint).
552 * @param[in] msg The message we want to send
553 * @param[in] size The size in bytes of the message
556 * 0 if there are no errors \n
557 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
558 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
559 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
560 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
561 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
562 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
563 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
564 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
567 int frescan_fna_send_sync
568 (const fna_endpoint_data_t *endpoint,
572 ERROR("not implemented\n");
577 * frescan_fna_send_async()
579 * This operation sends a message stored in msg and of length size
580 * through the given send endpoint. The operation is non-blocking and
581 * returns immediately.
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_async
601 (const fna_endpoint_data_t *endpoint,
606 frescan_send_params_t params;
608 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
609 "net:%u dest:%u chan:%u size:%u ss:%u\n",
610 endpoint->resource_id, endpoint->destination,
611 endpoint->stream_id, size, endpoint->vres);
613 params.net = (frescan_network_t)endpoint->resource_id;
614 params.to = (frescan_node_t)endpoint->destination;
615 params.channel = (frescan_channel_t)endpoint->stream_id;
616 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
617 params.ss = endpoint->vres;
619 ret = frescan_send(¶ms, (uint8_t *)msg, size);
621 ERROR ("could not send message\n");
629 * frescan_fna_receive_sync()
631 * This operation is used to receive messages from the network with a
632 * blocking behavior (if there are no messages this operation blocks
633 * the calling thread).
635 * When a message is available, it is copied to buffer (up to its size).
636 * The number of bytes copied is returned in received_bytes. The rest
637 * of the bytes of that message will be lost or not depending on the
638 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
640 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
641 * too small for the message received. In this case the message is
644 * Messages arriving at a receiver buffer that is full will be handled
645 * according to the queueing policy of the endpoint (overwrite oldest,
648 * @param[in] endpoint The receive endpoint we are receiving from.
649 * (resource_id is in the endpoint).
650 * @param[out] buffer Buffer for storing the received message
651 * @param[in] buffer_size The size in bytes of this buffer
652 * @param[out] received_bytes The actual number of received bytes
653 * @param[out] from Address of the sender node
656 * 0 if there are no errors \n
657 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
658 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
659 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
660 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
661 * FNA_ERR_NO_SPACE: if the message size is bigger than the
662 * provided buffer. \n
665 int frescan_fna_receive_sync
666 (const fna_endpoint_data_t *endpoint,
668 const size_t buffer_size,
669 size_t *received_bytes,
670 frsh_network_address_t *from)
673 frescan_recv_params_t params;
674 frescan_node_t frescan_from;
677 params.net = (frescan_network_t)endpoint->resource_id;
678 params.channel = (frescan_channel_t)endpoint->stream_id;
679 params.flags = FRESCAN_SYNC;
681 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
682 "net:%u chan:%u size:%u\n",
683 endpoint->resource_id, endpoint->stream_id, buffer_size);
685 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
686 received_bytes, &frescan_from, &prio);
689 ERROR ("error while receiving message");
693 *from = (frsh_network_address_t)frescan_from;
695 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
696 "msg received, from:%u bytes:%u prio:%u\n",
697 *from, *received_bytes, prio);
703 * frescan_fna_receive_async()
705 * This operation is similar to the previous one but it works in a non
706 * blocking (asynchronous) fashion. If no message is available it
707 * returns with error FNA_NO_MESSAGE.
709 * @param[in] endpoint The receive endpoint we are receiving from.
710 * (resource_id is in the endpoint).
711 * @param[out] buffer Buffer for storing the received message
712 * @param[in] buffer_size The size in bytes of this buffer
713 * @param[out] received_bytes The actual number of received bytes
714 * @param[out] from Address of the sender node
717 * 0 if there are no errors \n
718 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
719 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
720 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
721 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
722 * FNA_ERR_NO_SPACE: if the message size is bigger than the
723 * provided buffer. \n
724 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
727 int frescan_fna_receive_async
728 (const fna_endpoint_data_t *endpoint,
730 const size_t buffer_size,
731 size_t *received_bytes,
732 frsh_network_address_t *from)
734 ERROR("not implemented\n");
739 * frescan_fna_send_endpoint_get_status()
741 * This function tells the number of messages still pending in the
742 * endpoint queue, whether the network is up or down with some
743 * optional information which is protocol_dependent.
745 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
746 * @param[out] number_of_pending_messages The number of pending messages
747 * @param[out] network_status How is the network (up, down..)
748 * @param[out] protocol_status Protocol dependent status info
751 * 0 if there are no errors \n
752 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
753 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
754 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
755 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
758 int frescan_fna_send_endpoint_get_status
759 (const fna_endpoint_data_t *endpoint,
760 int *number_of_pending_messages,
761 frsh_endpoint_network_status_t *network_status,
762 frsh_protocol_status_t *protocol_status)
764 ERROR("not implemented\n");
769 * frescan_fna_receive_endpoint_created()
771 * This operation is a called from frsh_receive_endpoint_create with a
772 * receive_endpoint structure already filled.
774 * Receiving endpoints are not bound to any network vres, this is
775 * because don't originate any traffic.
777 * @param[in] endpoint the endpoint object.
780 * 0 if there are no errors \n
781 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
782 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
783 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
784 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
786 int frescan_fna_receive_endpoint_created
787 (fna_endpoint_data_t *endpoint)
789 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
794 * frescan_fna_receive_endpoint_get_pending_messages
796 * This function tells the number of messages still pending in the
797 * endpoint queue, whether the network is up or down and some optional
798 * information which is protocol dependent.
800 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
801 * @param[out] number_of_pending_messages The number of pending messages
802 * @param[out] network_status How is the network (up, down..)
803 * @param[out] protocol_status Protocol dependent status info
806 * 0 if there are no errors \n
807 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
808 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
809 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
810 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
813 int frescan_fna_receive_endpoint_get_status
814 (const fna_endpoint_data_t *endpoint,
815 int *number_of_pending_messages,
816 frsh_endpoint_network_status_t *network_status,
817 frsh_protocol_status_t *protocol_status)
819 ERROR("not implemented\n");
823 //////////////////////////////////////////////////////////////////////
824 // NETWORK CONFIGURATION FUNCTIONS
825 //////////////////////////////////////////////////////////////////////
828 * frescan_fna_network_get_max_message_size()
830 * This operation gives the maximum number of bytes that can be sent
831 * at a time through the send function when using the network designated by
832 * 'resource_id' and sending it to 'destination'.
834 * If the application needs to send bigger messages it will have to
837 * Some protocols, like IP, are capable of sending large messages
838 * (and use fragmentation internally) but other protocols don't.
840 * @param[in] resource_id The network we want the tx time from.
841 * @param[in] destination The destination address
842 * @param[out] max_size The maximum number of bytes for each message
845 * 0 if there are no errors \n
846 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
847 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
848 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
849 * a network accessible from the current processing node \n
850 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
854 int frescan_fna_network_get_max_message_size
855 (const frsh_resource_id_t resource_id,
856 const frsh_network_address_t destination,
859 ERROR("not implemented\n");
864 * frescan_fna_network_bytes_to_budget()
866 * This operation converts a number of bytes into a temporal budget for
867 * a specific network. Network overheads are not included here but are
868 * considered internally when negotiating a specific contract.
870 * @param[in] resource_id The network
871 * @param[in] nbytes Number of bytes
872 * @param[out] budget The network budget for nbytes
875 * 0 if there are no errors \n
876 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
877 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
878 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
879 * a network accessible from the current processing node \n
880 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
884 int frescan_fna_network_bytes_to_budget
885 (const frsh_resource_id_t resource_id,
887 struct timespec *budget)
889 int number_of_packets;
891 if (budget == NULL || nbytes < 0) {
895 // we measure the budget in number of FRESCAN frames (8 bytes)
896 number_of_packets = (int) ceil((double)nbytes / 8.0);
898 // we store the budget in number of packets instead of in time. We
899 // use a field in the timespec structure.
900 budget->tv_sec = number_of_packets;
902 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
903 "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
909 * frescan_fna_network_budget_to_bytes()
911 * This operation converts a temporal budget into a number of bytes for
912 * a specific network. Network overheads are not included.
914 * @param[in] resource_id The network
915 * @param[in] budget The network budget for nbytes
916 * @param[out] nbytes Number of bytes
919 * 0 if there are no errors \n
920 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
921 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
922 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
923 * a network accessible from the current processing node \n
924 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
925 * an invalid time value \n
928 int frescan_fna_network_budget_to_bytes
929 (const frsh_resource_id_t resource_id,
930 const struct timespec *budget,
933 int number_of_packets;
935 if (budget == NULL || nbytes == NULL) {
939 number_of_packets = budget->tv_sec;
941 *nbytes = number_of_packets * 8;
947 * frescan_fna_network_get_min_eff_budget()
949 * This operation gets the minimum effective budget for a network. Each message
950 * consumes a contracted budget in "chunks" (i.e: packets) that we call
951 * minimum effective budget.
953 * A negotiated contract, for N bytes in a period T, means that there is a
954 * virtual resource that reserves for the user:
956 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
958 * Note that if the user decides not to send these N bytes at once but, say,
959 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
960 * budget will become exhausted before sending all the bytes.
962 * @param[in] resource_id The network
963 * @param[out] budget The network budget
966 * 0 if there are no errors \n
967 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
968 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
969 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
970 * a network accessible from the current processing node \n
971 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
974 int frescan_fna_network_get_min_eff_budget
975 (const frsh_resource_id_t resource_id,
976 struct timespec *budget)
978 if (budget == NULL) {
987 // GLOBAL variable to install the network protocol in FRESCOR
989 fna_operations_t frescan_fna_operations = {
990 .fna_init = frescan_fna_init,
991 .fna_contract_negotiate = frescan_fna_contract_negotiate,
992 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
993 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
994 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
995 .fna_vres_destroy = frescan_fna_vres_destroy,
996 .fna_vres_get_contract = frescan_fna_vres_get_contract,
997 .fna_vres_get_usage = frescan_fna_vres_get_usage,
998 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
999 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1000 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1001 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1002 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1003 .fna_send_sync = frescan_fna_send_sync,
1004 .fna_send_async = frescan_fna_send_async,
1005 .fna_receive_sync = frescan_fna_receive_sync,
1006 .fna_receive_async = frescan_fna_receive_async,
1007 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1008 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1009 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1010 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1011 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1012 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1013 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget