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 "frsh.h" /* frsh_resource_id_t, .. */
17 #include "frescan.h" /* frescan_init, ... */
18 #include "frescan_data.h" /* frescan_contract_t, ... */
19 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
20 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
23 #include "frescan_debug.h" /* DEBUG, ERROR */
25 //////////////////////////////////////////////////////////////////////
27 //////////////////////////////////////////////////////////////////////
32 * This function will be hooked to the frsh_init function and it is
33 * intented to initialize the protocol and its structures.
35 * @param[in] resource_id The network we are referring to (a protocol
36 * could be able to handle several networks at the same time)
39 * 0 if there are no errors \n
40 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
41 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
42 * FNA_ERR_ALREADY_INITIALIZED:
43 * if the function has already been called before (with success) \n
46 int frescan_fna_init(const frsh_resource_id_t resource_id)
49 frescan_init_params_t init_params;
51 // TODO: resource_id must be relative or sth
52 // TODO: init_params must be configurable
53 init_params.net = (frescan_network_t)resource_id;
54 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
55 init_params.tx_fp_max_prio = 10;
56 init_params.rx_num_of_channels = 10;
57 init_params.rx_channel_max_prio = NULL;
59 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
61 ret = frescan_init(&init_params);
62 if (ret != 0) ERROR ("could not init FRESCAN");
64 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
66 ret = frescan_bwres_init(init_params.net);
67 if (ret != 0) ERROR ("could not init BWRES");
72 ///////////////////////////////////////////////////////////////////
74 ///////////////////////////////////////////////////////////////////
77 * frescan_fna_contract_negotiate()
79 * The operation negotiates a contract and if accepted it will return
80 * a fna_vres_id_t. It will also check that the given contract_id is unique
83 * If the on-line admission test is enabled, it determines whether the
84 * contract can be admitted or not based on the current contracts
85 * established in the network. Then it creates the vres and
86 * recalculates all necessary parameters for the contracts already
87 * present in the system.
89 * This is a potentially blocking operation, it returns when the
90 * system has either rejected the contract, or admitted it and made it
93 * @param[in] resource_id The network we are referring to (a protocol
94 * could be able to handle several networks at the same time)
95 * @param[in] contract The contract parameters to negotiate
96 * @param[out] vres The internal virtual resource id
99 * 0 if there are no errors (in this case it also means contract accepted) \n
100 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
101 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
102 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
103 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
104 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
105 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
106 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
109 int frescan_fna_contract_negotiate
110 (const frsh_resource_id_t resource_id,
111 const frsh_contract_t *contract,
116 frescan_contract_t frescan_contract;
118 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
119 "frsh contract->frescan contract\n");
121 // TODO: budget is stored as number of can frames in tv_sec
122 frescan_contract.min_values.budget = contract->budget_min.tv_sec;
123 frescan_contract.min_values.period = contract->period_max;
125 frescan_contract.max_values.budget = contract->budget_max.tv_sec;
126 frescan_contract.max_values.period = contract->period_min;
128 frescan_contract.prio = contract->preemption_level;
130 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
131 accepted = frescan_bwres_negotiate((frescan_network_t)resource_id,
133 &ss); // TODO: associate the contract with the ss
136 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
137 *vres = (fna_vres_id_t)ss;
139 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
146 * frescan_fna_contract_renegotiate_sync()
148 * The operation renegotiates a contract for an existing vres. If
149 * the on-line admission test is enabled it determines whether the
150 * contract can be admitted or not based on the current contracts
151 * established in the system. If it cannot be admitted, the old
152 * contract remains in effect and an error is returned. If it can be
153 * admitted, it recalculates all necessary parameters for the
154 * contracts already present in the system and returns zero. This is a
155 * potentially blocking operation; it returns when the system has
156 * either rejected the new contract, or admitted it and made it
159 * @param[in] resource_id The network we are referring to (a protocol
160 * could be able to handle several networks at the same time)
161 * @param[in] vres The internal virtual resource id to renegotiate
162 * @param[in] new_contract The new contract
165 * 0 if there are no errors (in this case it also means contract accepted) \n
166 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
167 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
168 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
169 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
170 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
171 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
172 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
175 int frescan_fna_contract_renegotiate_sync
176 (const frsh_resource_id_t resource_id,
177 const fna_vres_id_t vres,
178 const frsh_contract_t *new_contract)
180 ERROR("not implemented\n");
185 * frescan_fna_contract_renegotiate_async()
187 * The operation enqueues a renegotiate operation for an existing
188 * vres, and returns immediately. The renegotiate operation is
189 * performed asynchronously, as soon as it is practical; meanwhile the
190 * system operation will continue normally. When the renegotiation is
191 * made, if the on-line admission test is enabled it determines
192 * whether the contract can be admitted or not based on the current
193 * contracts established in the system. If it cannot be admitted, the
194 * old contract remains in effect. If it can be admitted, it
195 * recalculates all necessary parameters for the contracts already
196 * present in the system.
198 * When the operation is completed, notification is made to the
199 * caller, if requested, via a signal. The status of the operation (in
200 * progress, admitted, rejected) can be checked with the
201 * frsh_vres_get_renegotiation_status() operation. The argument
202 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
203 * signal value and in this case signal_info is to be sent with the signal.
205 * @param[in] resource_id The network we are referring to (a protocol
206 * could be able to handle several networks at the same time)
207 * @param[in] vres The internal virtual resource id to renegotiate
208 * @param[in] new_contract The new contract
209 * @param[in] signal_to_notify Signal number to use to notify vres of
210 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
211 * @param[in] signal_info: Associated info that will come with the signal.
212 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
215 * 0 if there are no errors \n
216 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
217 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
218 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
219 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
220 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
221 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
222 * NULL nor a valid POSIX signal \n
225 int frescan_fna_contract_renegotiate_async
226 (const frsh_resource_id_t resource_id,
227 const fna_vres_id_t vres,
228 const frsh_contract_t *new_contract,
229 frsh_signal_t signal_to_notify,
230 frsh_signal_info_t signal_info)
232 ERROR("not implemented\n");
237 * frescan_fna_vres_get_renegotiation_status()
239 * The operation reports on the status of the last renegotiation
240 * operation enqueued for the specified vres. It is callable even
241 * after notification of the completion of such operation, if
244 * If the vres is not and has not been involved in any of the
245 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
246 * operations, the status returned is FNA_NOT_REQUESTED
248 * @param[in] resource_id The network we are referring to (a protocol
249 * could be able to handle several networks at the same time)
250 * @param[in] vres The internal virtual resource id we want the status from
251 * @param[in] renegotiation_status The status of the last renegotiation on
252 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
253 * FRSH_RS_NOT_REQUESTED)
256 * 0 if there are no errors \n
257 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
258 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
259 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
260 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
261 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
264 int frescan_fna_vres_get_renegotiation_status
265 (const frsh_resource_id_t resource_id,
266 const fna_vres_id_t vres,
267 frsh_renegotiation_status_t *renegotiation_status)
269 ERROR("not implemented\n");
274 * frescan_fna_vres_destroy()
276 * The operation eliminates the specified vres
277 * and recalculates all necessary parameters for the contracts
278 * remaining in the system. This is a potentially blocking operation;
279 * it returns when the system has made the changes effective.
281 * @param[in] resource_id The network we are referring to (a protocol
282 * could be able to handle several networks at the same time)
283 * @param[in] vres The internal virtual resource id to destroy
286 * 0 if there are no errors \n
287 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
288 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
289 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
290 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
291 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
294 int frescan_fna_vres_destroy
295 (const frsh_resource_id_t resource_id,
296 const fna_vres_id_t vres)
298 ERROR("not implemented\n");
303 * frescan_fna_vres_get_contract()
305 * This operation stores the contract parameters currently associated
306 * with the specified vres in the variable pointed to by
307 * contract. It returns an error if the vres_id is not recognised.
309 * @param[in] resource_id The network we are referring to (a protocol
310 * could be able to handle several networks at the same time)
311 * @param[in] vres The internal virtual resource id
312 * @param[out] contract The contract parameters that we want
315 * 0 if there are no errors \n
316 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
317 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
318 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
319 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
320 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
323 int frescan_fna_vres_get_contract
324 (const frsh_resource_id_t resource_id,
325 const fna_vres_id_t vres,
326 frsh_contract_t *contract)
328 ERROR("not implemented\n");
333 * frescan_fna_vres_get_usage()
335 * This function gets the execution time spent by all messages that have been
336 * sent through the specified vres.
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
341 * @param[out] usage Execution time spent by this vres
344 * 0 if there are no errors \n
345 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
346 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
347 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
348 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
349 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
352 int frescan_fna_vres_get_usage
353 (const frsh_resource_id_t resource_id,
354 const fna_vres_id_t vres,
355 struct timespec *usage)
357 ERROR("not implemented\n");
362 * frescan_fna_vres_get_remaining_budget()
364 * This function stores in the variable pointed to by budget the
365 * remaining execution-time budget associated with the specified
366 * vres in the present period.
368 * @param[in] resource_id The network we are referring to (a protocol
369 * could be able to handle several networks at the same time)
370 * @param[in] vres The internal virtual resource id
371 * @param[out] remaining_budget The remaining budget for this period
374 * 0 if there are no errors \n
375 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
376 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
377 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
378 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
379 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
382 int frescan_fna_vres_get_remaining_budget
383 (const frsh_resource_id_t resource_id,
384 const fna_vres_id_t vres,
385 struct timespec *remaining_budget)
387 ERROR("not implemented\n");
392 * frescan_fna_vres_get_budget_and_period()
394 * This function gets the budget and period associated with the specified vres
395 * for each period. If one of these pointers is NULL, the corresponding
396 * information is not stored.
398 * @param[in] resource_id The network we are referring to (a protocol
399 * could be able to handle several networks at the same time)
400 * @param[in] vres The internal virtual resource id
401 * @param[out] budget The budget associated to vres
402 * @param[out] period The period associated to vres
405 * 0 if there are no errors \n
406 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
407 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
408 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
409 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
410 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
413 int frescan_fna_vres_get_budget_and_period
414 (const frsh_resource_id_t resource_id,
415 const fna_vres_id_t vres,
416 struct timespec *budget,
417 struct timespec *period)
419 ERROR("not implemented\n");
425 ///////////////////////////////////////////////////////////////////
426 // SPARE CAPACITY FUNCIONS
427 ///////////////////////////////////////////////////////////////////
430 * @defgroup fnaspare FNA Spare Capacity
433 * The following functions are used to get spare capacity data
439 * frescan_fna_resource_get_capacity()
441 * This operation gets the spare capacity currently assigned to a importance
442 * level. If we divide this value by UINT32_MAX we will get the network
443 * utilization associated to the spare capacity of a importance level.
445 * The following is typically in stdint.h: \n
446 * - typedef unsigned int uint32_t; \n
447 * - # define UINT32_MAX (4294967295U) \n
449 * @param[in] resource_id The network we are referring to (a protocol
450 * could be able to handle several networks at the same time)
451 * @param[in] importance The importance we want the capacity of
452 * @param[out] capacity The spare capacity for that importance level
455 * 0 if there are no errors \n
456 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
457 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
458 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
459 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
462 int frescan_fna_resource_get_capacity
463 (const frsh_resource_id_t resource_id,
464 const int importance,
467 ERROR("not implemented\n");
472 * frescan_fna_resource_get_total_weight()
474 * This function gets the sum of the weight parameters for all vres in a
475 * network of an importance level.
477 * @param[in] resource_id The network we are referring to (a protocol
478 * could be able to handle several networks at the same time)
479 * @param[in] importance The importance we want the total weight of
480 * @param[out] total_weight The total weight for that importance level
483 * 0 if there are no errors \n
484 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \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_resource_get_total_weight
491 (const frsh_resource_id_t resource_id,
492 const int importance,
495 ERROR("not implemented\n");
500 * frescan_fna_vres_decrease_capacity()
502 * This function allows to ask for less budget and period than what we
503 * received. The request must be compatible with the rest of contract
504 * parameters of the vres. If we want to recover the released capacity
505 * we will need to renegotiate.
507 * @param[in] resource_id The network we are referring to (a protocol
508 * could be able to handle several networks at the same time)
509 * @param[in] vres The internal virtual resource id
510 * @param[in] new_budget The new_budget
511 * @param[in] new_period The new Period
514 * 0 if there are no errors \n
515 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
516 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
517 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
518 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
519 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
520 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
524 int frescan_fna_vres_decrease_capacity
525 (const frsh_resource_id_t resource_id,
526 const fna_vres_id_t vres,
527 const struct timespec new_budget,
528 const struct timespec new_period)
530 ERROR("not implemented\n");
534 ///////////////////////////////////////////////////////////////////
535 // SEND RECEIVE OPERATIONS
536 ///////////////////////////////////////////////////////////////////
539 * frescan_fna_send_sync()
541 * Similar to previous function but now the sending thread gets blocked
542 * until the message is already sent to the network.
544 * @param[in] endpoint The send endpoint we are sending through. It must
545 * be bound to a virtual resource (resource_id is in the endpoint).
546 * @param[in] msg The message we want to send
547 * @param[in] size The size in bytes of the message
550 * 0 if there are no errors \n
551 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
552 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
553 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
554 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
555 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
556 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
557 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
558 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
561 int frescan_fna_send_sync
562 (const fna_endpoint_data_t *endpoint,
566 ERROR("not implemented\n");
571 * frescan_fna_send_async()
573 * This operation sends a message stored in msg and of length size
574 * through the given send endpoint. The operation is non-blocking and
575 * returns immediately.
577 * @param[in] endpoint The send endpoint we are sending through. It must
578 * be bound to a virtual resource (resource_id is in the endpoint).
579 * @param[in] msg The message we want to send
580 * @param[in] size The size in bytes of the message
583 * 0 if there are no errors \n
584 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
585 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
586 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
587 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
588 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
589 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
590 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
591 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
594 int frescan_fna_send_async
595 (const fna_endpoint_data_t *endpoint,
600 frescan_send_params_t params;
602 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
603 "net:%u dest:%u chan:%u size:%u ss:%u\n",
604 endpoint->resource_id, endpoint->destination,
605 endpoint->stream_id, size, endpoint->vres);
607 params.net = (frescan_network_t)endpoint->resource_id;
608 params.to = (frescan_node_t)endpoint->destination;
609 params.channel = (frescan_channel_t)endpoint->stream_id;
610 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
611 params.ss = endpoint->vres;
613 ret = frescan_send(¶ms, (uint8_t *)msg, size);
615 ERROR ("could not send message\n");
623 * frescan_fna_receive_sync()
625 * This operation is used to receive messages from the network with a
626 * blocking behavior (if there are no messages this operation blocks
627 * the calling thread).
629 * When a message is available, it is copied to buffer (up to its size).
630 * The number of bytes copied is returned in received_bytes. The rest
631 * of the bytes of that message will be lost or not depending on the
632 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
634 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
635 * too small for the message received. In this case the message is
638 * Messages arriving at a receiver buffer that is full will be handled
639 * according to the queueing policy of the endpoint (overwrite oldest,
642 * @param[in] endpoint The receive endpoint we are receiving from.
643 * (resource_id is in the endpoint).
644 * @param[out] buffer Buffer for storing the received message
645 * @param[in] buffer_size The size in bytes of this buffer
646 * @param[out] received_bytes The actual number of received bytes
647 * @param[out] from Address of the sender node
650 * 0 if there are no errors \n
651 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
652 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
653 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
654 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
655 * FNA_ERR_NO_SPACE: if the message size is bigger than the
656 * provided buffer. \n
659 int frescan_fna_receive_sync
660 (const fna_endpoint_data_t *endpoint,
662 const size_t buffer_size,
663 size_t *received_bytes,
664 frsh_network_address_t *from)
667 frescan_recv_params_t params;
668 frescan_node_t frescan_from;
671 params.net = (frescan_network_t)endpoint->resource_id;
672 params.channel = (frescan_channel_t)endpoint->stream_id;
673 params.flags = FRESCAN_SYNC;
675 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
676 "net:%u chan:%u size:%u\n",
677 endpoint->resource_id, endpoint->stream_id, buffer_size);
679 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
680 received_bytes, &frescan_from, &prio);
683 ERROR ("error while receiving message");
687 *from = (frsh_network_address_t)frescan_from;
689 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
690 "msg received, from:%u bytes:%u prio:%u\n",
691 *from, *received_bytes, prio);
697 * frescan_fna_receive_async()
699 * This operation is similar to the previous one but it works in a non
700 * blocking (asynchronous) fashion. If no message is available it
701 * returns with error FNA_NO_MESSAGE.
703 * @param[in] endpoint The receive endpoint we are receiving from.
704 * (resource_id is in the endpoint).
705 * @param[out] buffer Buffer for storing the received message
706 * @param[in] buffer_size The size in bytes of this buffer
707 * @param[out] received_bytes The actual number of received bytes
708 * @param[out] from Address of the sender node
711 * 0 if there are no errors \n
712 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
713 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
714 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
715 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
716 * FNA_ERR_NO_SPACE: if the message size is bigger than the
717 * provided buffer. \n
718 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
721 int frescan_fna_receive_async
722 (const fna_endpoint_data_t *endpoint,
724 const size_t buffer_size,
725 size_t *received_bytes,
726 frsh_network_address_t *from)
728 ERROR("not implemented\n");
733 * frescan_fna_send_endpoint_get_status()
735 * This function tells the number of messages still pending in the
736 * endpoint queue, whether the network is up or down with some
737 * optional information which is protocol_dependent.
739 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
740 * @param[out] number_of_pending_messages The number of pending messages
741 * @param[out] network_status How is the network (up, down..)
742 * @param[out] protocol_status Protocol dependent status info
745 * 0 if there are no errors \n
746 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
747 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
748 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
749 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
752 int frescan_fna_send_endpoint_get_status
753 (const fna_endpoint_data_t *endpoint,
754 int *number_of_pending_messages,
755 frsh_endpoint_network_status_t *network_status,
756 frsh_protocol_status_t *protocol_status)
758 ERROR("not implemented\n");
763 * frescan_fna_receive_endpoint_created()
765 * This operation is a called from frsh_receive_endpoint_create with a
766 * receive_endpoint structure already filled.
768 * Receiving endpoints are not bound to any network vres, this is
769 * because don't originate any traffic.
771 * @param[in] endpoint the endpoint object.
774 * 0 if there are no errors \n
775 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
776 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
777 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
778 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
780 int frescan_fna_receive_endpoint_created
781 (fna_endpoint_data_t *endpoint)
783 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
788 * frescan_fna_receive_endpoint_get_pending_messages
790 * This function tells the number of messages still pending in the
791 * endpoint queue, whether the network is up or down and some optional
792 * information which is protocol dependent.
794 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
795 * @param[out] number_of_pending_messages The number of pending messages
796 * @param[out] network_status How is the network (up, down..)
797 * @param[out] protocol_status Protocol dependent status info
800 * 0 if there are no errors \n
801 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
802 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
803 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
804 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
807 int frescan_fna_receive_endpoint_get_status
808 (const fna_endpoint_data_t *endpoint,
809 int *number_of_pending_messages,
810 frsh_endpoint_network_status_t *network_status,
811 frsh_protocol_status_t *protocol_status)
813 ERROR("not implemented\n");
817 //////////////////////////////////////////////////////////////////////
818 // NETWORK CONFIGURATION FUNCTIONS
819 //////////////////////////////////////////////////////////////////////
822 * frescan_fna_network_get_max_message_size()
824 * This operation gives the maximum number of bytes that can be sent
825 * at a time through the send function when using the network designated by
826 * 'resource_id' and sending it to 'destination'.
828 * If the application needs to send bigger messages it will have to
831 * Some protocols, like IP, are capable of sending large messages
832 * (and use fragmentation internally) but other protocols don't.
834 * @param[in] resource_id The network we want the tx time from.
835 * @param[in] destination The destination address
836 * @param[out] max_size The maximum number of bytes for each message
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 resource id does not represent
843 * a network accessible from the current processing node \n
844 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
848 int frescan_fna_network_get_max_message_size
849 (const frsh_resource_id_t resource_id,
850 const frsh_network_address_t destination,
853 ERROR("not implemented\n");
858 * frescan_fna_network_bytes_to_budget()
860 * This operation converts a number of bytes into a temporal budget for
861 * a specific network. Network overheads are not included here but are
862 * considered internally when negotiating a specific contract.
864 * @param[in] resource_id The network
865 * @param[in] nbytes Number of bytes
866 * @param[out] budget The network budget for nbytes
869 * 0 if there are no errors \n
870 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
871 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
872 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
873 * a network accessible from the current processing node \n
874 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
878 int frescan_fna_network_bytes_to_budget
879 (const frsh_resource_id_t resource_id,
881 struct timespec *budget)
883 int number_of_packets;
885 if (budget == NULL || nbytes < 0) {
889 // we measure the budget in number of FRESCAN frames (8 bytes)
890 number_of_packets = nbytes / 8 + 1;
892 // we store the budget in number of packets instead of in time. We
893 // use a field in the timespec structure.
894 budget->tv_sec = number_of_packets;
896 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
897 "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
903 * frescan_fna_network_budget_to_bytes()
905 * This operation converts a temporal budget into a number of bytes for
906 * a specific network. Network overheads are not included.
908 * @param[in] resource_id The network
909 * @param[in] budget The network budget for nbytes
910 * @param[out] nbytes Number of bytes
913 * 0 if there are no errors \n
914 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
915 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
916 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
917 * a network accessible from the current processing node \n
918 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
919 * an invalid time value \n
922 int frescan_fna_network_budget_to_bytes
923 (const frsh_resource_id_t resource_id,
924 const struct timespec *budget,
927 int number_of_packets;
929 if (budget == NULL || nbytes == NULL) {
933 number_of_packets = budget->tv_sec;
935 *nbytes = number_of_packets * 8;
941 * frescan_fna_network_get_min_eff_budget()
943 * This operation gets the minimum effective budget for a network. Each message
944 * consumes a contracted budget in "chunks" (i.e: packets) that we call
945 * minimum effective budget.
947 * A negotiated contract, for N bytes in a period T, means that there is a
948 * virtual resource that reserves for the user:
950 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
952 * Note that if the user decides not to send these N bytes at once but, say,
953 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
954 * budget will become exhausted before sending all the bytes.
956 * @param[in] resource_id The network
957 * @param[out] budget The network budget
960 * 0 if there are no errors \n
961 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
962 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
963 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
964 * a network accessible from the current processing node \n
965 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
968 int frescan_fna_network_get_min_eff_budget
969 (const frsh_resource_id_t resource_id,
970 struct timespec *budget)
972 if (budget == NULL) {
981 // GLOBAL variable to install the network protocol in FRESCOR
983 fna_operations_t frescan_fna_operations = {
984 .fna_init = frescan_fna_init,
985 .fna_contract_negotiate = frescan_fna_contract_negotiate,
986 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
987 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
988 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
989 .fna_vres_destroy = frescan_fna_vres_destroy,
990 .fna_vres_get_contract = frescan_fna_vres_get_contract,
991 .fna_vres_get_usage = frescan_fna_vres_get_usage,
992 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
993 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
994 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
995 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
996 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
997 .fna_send_sync = frescan_fna_send_sync,
998 .fna_send_async = frescan_fna_send_async,
999 .fna_receive_sync = frescan_fna_receive_sync,
1000 .fna_receive_async = frescan_fna_receive_async,
1001 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1002 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1003 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1004 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1005 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1006 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1007 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget