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,
117 frescan_contract_t frescan_contract;
119 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
120 "frsh contract->frescan contract\n");
122 // NOTE: budget is stored as number of can frames in tv_sec
123 frescan_contract.min_values.budget = contract->budget_min.tv_sec;
124 frescan_contract.min_values.period = contract->period_max;
126 frescan_contract.max_values.budget = contract->budget_max.tv_sec;
127 frescan_contract.max_values.period = contract->period_min;
129 // TODO: put 0 if we want the sa module to assign the prios
130 frescan_contract.prio = contract->preemption_level;
132 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
133 ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
137 if (ret != 0) return -1;
139 if (accepted == true) {
140 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
141 *vres = (fna_vres_id_t)ss;
144 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
145 return -1; // TODO: change to constant FNA_REJECTED
150 * frescan_fna_contract_renegotiate_sync()
152 * The operation renegotiates a contract for an existing vres. If
153 * the on-line admission test is enabled it determines whether the
154 * contract can be admitted or not based on the current contracts
155 * established in the system. If it cannot be admitted, the old
156 * contract remains in effect and an error is returned. If it can be
157 * admitted, it recalculates all necessary parameters for the
158 * contracts already present in the system and returns zero. This is a
159 * potentially blocking operation; it returns when the system has
160 * either rejected the new contract, or admitted it and made it
163 * @param[in] resource_id The network we are referring to (a protocol
164 * could be able to handle several networks at the same time)
165 * @param[in] vres The internal virtual resource id to renegotiate
166 * @param[in] new_contract The new contract
169 * 0 if there are no errors (in this case it also means contract accepted) \n
170 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
171 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
172 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
173 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
174 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
175 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
176 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
179 int frescan_fna_contract_renegotiate_sync
180 (const frsh_resource_id_t resource_id,
181 const fna_vres_id_t vres,
182 const frsh_contract_t *new_contract)
184 ERROR("not implemented\n");
189 * frescan_fna_contract_renegotiate_async()
191 * The operation enqueues a renegotiate operation for an existing
192 * vres, and returns immediately. The renegotiate operation is
193 * performed asynchronously, as soon as it is practical; meanwhile the
194 * system operation will continue normally. When the renegotiation is
195 * made, if the on-line admission test is enabled it determines
196 * whether the contract can be admitted or not based on the current
197 * contracts established in the system. If it cannot be admitted, the
198 * old contract remains in effect. If it can be admitted, it
199 * recalculates all necessary parameters for the contracts already
200 * present in the system.
202 * When the operation is completed, notification is made to the
203 * caller, if requested, via a signal. The status of the operation (in
204 * progress, admitted, rejected) can be checked with the
205 * frsh_vres_get_renegotiation_status() operation. The argument
206 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
207 * signal value and in this case signal_info is to be sent with the signal.
209 * @param[in] resource_id The network we are referring to (a protocol
210 * could be able to handle several networks at the same time)
211 * @param[in] vres The internal virtual resource id to renegotiate
212 * @param[in] new_contract The new contract
213 * @param[in] signal_to_notify Signal number to use to notify vres of
214 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
215 * @param[in] signal_info: Associated info that will come with the signal.
216 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
219 * 0 if there are no errors \n
220 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
221 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
222 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
223 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
224 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
225 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
226 * NULL nor a valid POSIX signal \n
229 int frescan_fna_contract_renegotiate_async
230 (const frsh_resource_id_t resource_id,
231 const fna_vres_id_t vres,
232 const frsh_contract_t *new_contract,
233 frsh_signal_t signal_to_notify,
234 frsh_signal_info_t signal_info)
236 ERROR("not implemented\n");
241 * frescan_fna_vres_get_renegotiation_status()
243 * The operation reports on the status of the last renegotiation
244 * operation enqueued for the specified vres. It is callable even
245 * after notification of the completion of such operation, if
248 * If the vres is not and has not been involved in any of the
249 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
250 * operations, the status returned is FNA_NOT_REQUESTED
252 * @param[in] resource_id The network we are referring to (a protocol
253 * could be able to handle several networks at the same time)
254 * @param[in] vres The internal virtual resource id we want the status from
255 * @param[in] renegotiation_status The status of the last renegotiation on
256 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
257 * FRSH_RS_NOT_REQUESTED)
260 * 0 if there are no errors \n
261 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
262 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
263 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
264 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
265 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
268 int frescan_fna_vres_get_renegotiation_status
269 (const frsh_resource_id_t resource_id,
270 const fna_vres_id_t vres,
271 frsh_renegotiation_status_t *renegotiation_status)
273 ERROR("not implemented\n");
278 * frescan_fna_vres_destroy()
280 * The operation eliminates the specified vres
281 * and recalculates all necessary parameters for the contracts
282 * remaining in the system. This is a potentially blocking operation;
283 * it returns when the system has made the changes effective.
285 * @param[in] resource_id The network we are referring to (a protocol
286 * could be able to handle several networks at the same time)
287 * @param[in] vres The internal virtual resource id to destroy
290 * 0 if there are no errors \n
291 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
292 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
293 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
294 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
295 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
298 int frescan_fna_vres_destroy
299 (const frsh_resource_id_t resource_id,
300 const fna_vres_id_t vres)
302 ERROR("not implemented\n");
307 * frescan_fna_vres_get_contract()
309 * This operation stores the contract parameters currently associated
310 * with the specified vres in the variable pointed to by
311 * contract. It returns an error if the vres_id is not recognised.
313 * @param[in] resource_id The network we are referring to (a protocol
314 * could be able to handle several networks at the same time)
315 * @param[in] vres The internal virtual resource id
316 * @param[out] contract The contract parameters that we want
319 * 0 if there are no errors \n
320 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
321 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
322 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
323 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
324 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
327 int frescan_fna_vres_get_contract
328 (const frsh_resource_id_t resource_id,
329 const fna_vres_id_t vres,
330 frsh_contract_t *contract)
332 ERROR("not implemented\n");
337 * frescan_fna_vres_get_usage()
339 * This function gets the execution time spent by all messages that have been
340 * sent through the specified vres.
342 * @param[in] resource_id The network we are referring to (a protocol
343 * could be able to handle several networks at the same time)
344 * @param[in] vres The internal virtual resource id
345 * @param[out] usage Execution time spent by this vres
348 * 0 if there are no errors \n
349 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
350 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
351 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
352 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
353 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
356 int frescan_fna_vres_get_usage
357 (const frsh_resource_id_t resource_id,
358 const fna_vres_id_t vres,
359 struct timespec *usage)
361 ERROR("not implemented\n");
366 * frescan_fna_vres_get_remaining_budget()
368 * This function stores in the variable pointed to by budget the
369 * remaining execution-time budget associated with the specified
370 * vres in the present period.
372 * @param[in] resource_id The network we are referring to (a protocol
373 * could be able to handle several networks at the same time)
374 * @param[in] vres The internal virtual resource id
375 * @param[out] remaining_budget The remaining budget for this period
378 * 0 if there are no errors \n
379 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
380 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
381 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
382 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
383 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
386 int frescan_fna_vres_get_remaining_budget
387 (const frsh_resource_id_t resource_id,
388 const fna_vres_id_t vres,
389 struct timespec *remaining_budget)
391 ERROR("not implemented\n");
396 * frescan_fna_vres_get_budget_and_period()
398 * This function gets the budget and period associated with the specified vres
399 * for each period. If one of these pointers is NULL, the corresponding
400 * information is not stored.
402 * @param[in] resource_id The network we are referring to (a protocol
403 * could be able to handle several networks at the same time)
404 * @param[in] vres The internal virtual resource id
405 * @param[out] budget The budget associated to vres
406 * @param[out] period The period associated to vres
409 * 0 if there are no errors \n
410 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
411 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
412 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
413 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
414 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
417 int frescan_fna_vres_get_budget_and_period
418 (const frsh_resource_id_t resource_id,
419 const fna_vres_id_t vres,
420 struct timespec *budget,
421 struct timespec *period)
423 ERROR("not implemented\n");
429 ///////////////////////////////////////////////////////////////////
430 // SPARE CAPACITY FUNCIONS
431 ///////////////////////////////////////////////////////////////////
434 * @defgroup fnaspare FNA Spare Capacity
437 * The following functions are used to get spare capacity data
443 * frescan_fna_resource_get_capacity()
445 * This operation gets the spare capacity currently assigned to a importance
446 * level. If we divide this value by UINT32_MAX we will get the network
447 * utilization associated to the spare capacity of a importance level.
449 * The following is typically in stdint.h: \n
450 * - typedef unsigned int uint32_t; \n
451 * - # define UINT32_MAX (4294967295U) \n
453 * @param[in] resource_id The network we are referring to (a protocol
454 * could be able to handle several networks at the same time)
455 * @param[in] importance The importance we want the capacity of
456 * @param[out] capacity The spare capacity for that importance level
459 * 0 if there are no errors \n
460 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
461 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
462 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
463 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
466 int frescan_fna_resource_get_capacity
467 (const frsh_resource_id_t resource_id,
468 const int importance,
471 ERROR("not implemented\n");
476 * frescan_fna_resource_get_total_weight()
478 * This function gets the sum of the weight parameters for all vres in a
479 * network of an importance level.
481 * @param[in] resource_id The network we are referring to (a protocol
482 * could be able to handle several networks at the same time)
483 * @param[in] importance The importance we want the total weight of
484 * @param[out] total_weight The total weight for that importance level
487 * 0 if there are no errors \n
488 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
489 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
490 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
491 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
494 int frescan_fna_resource_get_total_weight
495 (const frsh_resource_id_t resource_id,
496 const int importance,
499 ERROR("not implemented\n");
504 * frescan_fna_vres_decrease_capacity()
506 * This function allows to ask for less budget and period than what we
507 * received. The request must be compatible with the rest of contract
508 * parameters of the vres. If we want to recover the released capacity
509 * we will need to renegotiate.
511 * @param[in] resource_id The network we are referring to (a protocol
512 * could be able to handle several networks at the same time)
513 * @param[in] vres The internal virtual resource id
514 * @param[in] new_budget The new_budget
515 * @param[in] new_period The new Period
518 * 0 if there are no errors \n
519 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
520 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
521 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
522 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
523 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
524 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
528 int frescan_fna_vres_decrease_capacity
529 (const frsh_resource_id_t resource_id,
530 const fna_vres_id_t vres,
531 const struct timespec new_budget,
532 const struct timespec new_period)
534 ERROR("not implemented\n");
538 ///////////////////////////////////////////////////////////////////
539 // SEND RECEIVE OPERATIONS
540 ///////////////////////////////////////////////////////////////////
543 * frescan_fna_send_sync()
545 * Similar to previous function but now the sending thread gets blocked
546 * until the message is already sent to the network.
548 * @param[in] endpoint The send endpoint we are sending through. It must
549 * be bound to a virtual resource (resource_id is in the endpoint).
550 * @param[in] msg The message we want to send
551 * @param[in] size The size in bytes of the message
554 * 0 if there are no errors \n
555 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
556 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
557 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
558 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
559 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
560 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
561 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
562 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
565 int frescan_fna_send_sync
566 (const fna_endpoint_data_t *endpoint,
570 ERROR("not implemented\n");
575 * frescan_fna_send_async()
577 * This operation sends a message stored in msg and of length size
578 * through the given send endpoint. The operation is non-blocking and
579 * returns immediately.
581 * @param[in] endpoint The send endpoint we are sending through. It must
582 * be bound to a virtual resource (resource_id is in the endpoint).
583 * @param[in] msg The message we want to send
584 * @param[in] size The size in bytes of the message
587 * 0 if there are no errors \n
588 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
589 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
590 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
591 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
592 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
593 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
594 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
595 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
598 int frescan_fna_send_async
599 (const fna_endpoint_data_t *endpoint,
604 frescan_send_params_t params;
606 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
607 "net:%u dest:%u chan:%u size:%u ss:%u\n",
608 endpoint->resource_id, endpoint->destination,
609 endpoint->stream_id, size, endpoint->vres);
611 params.net = (frescan_network_t)endpoint->resource_id;
612 params.to = (frescan_node_t)endpoint->destination;
613 params.channel = (frescan_channel_t)endpoint->stream_id;
614 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
615 params.ss = endpoint->vres;
617 ret = frescan_send(¶ms, (uint8_t *)msg, size);
619 ERROR ("could not send message\n");
627 * frescan_fna_receive_sync()
629 * This operation is used to receive messages from the network with a
630 * blocking behavior (if there are no messages this operation blocks
631 * the calling thread).
633 * When a message is available, it is copied to buffer (up to its size).
634 * The number of bytes copied is returned in received_bytes. The rest
635 * of the bytes of that message will be lost or not depending on the
636 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
638 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
639 * too small for the message received. In this case the message is
642 * Messages arriving at a receiver buffer that is full will be handled
643 * according to the queueing policy of the endpoint (overwrite oldest,
646 * @param[in] endpoint The receive endpoint we are receiving from.
647 * (resource_id is in the endpoint).
648 * @param[out] buffer Buffer for storing the received message
649 * @param[in] buffer_size The size in bytes of this buffer
650 * @param[out] received_bytes The actual number of received bytes
651 * @param[out] from Address of the sender node
654 * 0 if there are no errors \n
655 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
656 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
657 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
658 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
659 * FNA_ERR_NO_SPACE: if the message size is bigger than the
660 * provided buffer. \n
663 int frescan_fna_receive_sync
664 (const fna_endpoint_data_t *endpoint,
666 const size_t buffer_size,
667 size_t *received_bytes,
668 frsh_network_address_t *from)
671 frescan_recv_params_t params;
672 frescan_node_t frescan_from;
675 params.net = (frescan_network_t)endpoint->resource_id;
676 params.channel = (frescan_channel_t)endpoint->stream_id;
677 params.flags = FRESCAN_SYNC;
679 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
680 "net:%u chan:%u size:%u\n",
681 endpoint->resource_id, endpoint->stream_id, buffer_size);
683 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
684 received_bytes, &frescan_from, &prio);
687 ERROR ("error while receiving message");
691 *from = (frsh_network_address_t)frescan_from;
693 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
694 "msg received, from:%u bytes:%u prio:%u\n",
695 *from, *received_bytes, prio);
701 * frescan_fna_receive_async()
703 * This operation is similar to the previous one but it works in a non
704 * blocking (asynchronous) fashion. If no message is available it
705 * returns with error FNA_NO_MESSAGE.
707 * @param[in] endpoint The receive endpoint we are receiving from.
708 * (resource_id is in the endpoint).
709 * @param[out] buffer Buffer for storing the received message
710 * @param[in] buffer_size The size in bytes of this buffer
711 * @param[out] received_bytes The actual number of received bytes
712 * @param[out] from Address of the sender node
715 * 0 if there are no errors \n
716 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
717 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
718 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
719 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
720 * FNA_ERR_NO_SPACE: if the message size is bigger than the
721 * provided buffer. \n
722 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
725 int frescan_fna_receive_async
726 (const fna_endpoint_data_t *endpoint,
728 const size_t buffer_size,
729 size_t *received_bytes,
730 frsh_network_address_t *from)
732 ERROR("not implemented\n");
737 * frescan_fna_send_endpoint_get_status()
739 * This function tells the number of messages still pending in the
740 * endpoint queue, whether the network is up or down with some
741 * optional information which is protocol_dependent.
743 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
744 * @param[out] number_of_pending_messages The number of pending messages
745 * @param[out] network_status How is the network (up, down..)
746 * @param[out] protocol_status Protocol dependent status info
749 * 0 if there are no errors \n
750 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
751 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
752 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
753 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
756 int frescan_fna_send_endpoint_get_status
757 (const fna_endpoint_data_t *endpoint,
758 int *number_of_pending_messages,
759 frsh_endpoint_network_status_t *network_status,
760 frsh_protocol_status_t *protocol_status)
762 ERROR("not implemented\n");
767 * frescan_fna_receive_endpoint_created()
769 * This operation is a called from frsh_receive_endpoint_create with a
770 * receive_endpoint structure already filled.
772 * Receiving endpoints are not bound to any network vres, this is
773 * because don't originate any traffic.
775 * @param[in] endpoint the endpoint object.
778 * 0 if there are no errors \n
779 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
780 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
781 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
782 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
784 int frescan_fna_receive_endpoint_created
785 (fna_endpoint_data_t *endpoint)
787 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
792 * frescan_fna_receive_endpoint_get_pending_messages
794 * This function tells the number of messages still pending in the
795 * endpoint queue, whether the network is up or down and some optional
796 * information which is protocol dependent.
798 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
799 * @param[out] number_of_pending_messages The number of pending messages
800 * @param[out] network_status How is the network (up, down..)
801 * @param[out] protocol_status Protocol dependent status info
804 * 0 if there are no errors \n
805 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
806 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
807 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
808 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
811 int frescan_fna_receive_endpoint_get_status
812 (const fna_endpoint_data_t *endpoint,
813 int *number_of_pending_messages,
814 frsh_endpoint_network_status_t *network_status,
815 frsh_protocol_status_t *protocol_status)
817 ERROR("not implemented\n");
821 //////////////////////////////////////////////////////////////////////
822 // NETWORK CONFIGURATION FUNCTIONS
823 //////////////////////////////////////////////////////////////////////
826 * frescan_fna_network_get_max_message_size()
828 * This operation gives the maximum number of bytes that can be sent
829 * at a time through the send function when using the network designated by
830 * 'resource_id' and sending it to 'destination'.
832 * If the application needs to send bigger messages it will have to
835 * Some protocols, like IP, are capable of sending large messages
836 * (and use fragmentation internally) but other protocols don't.
838 * @param[in] resource_id The network we want the tx time from.
839 * @param[in] destination The destination address
840 * @param[out] max_size The maximum number of bytes for each message
843 * 0 if there are no errors \n
844 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
845 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
846 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
847 * a network accessible from the current processing node \n
848 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
852 int frescan_fna_network_get_max_message_size
853 (const frsh_resource_id_t resource_id,
854 const frsh_network_address_t destination,
857 ERROR("not implemented\n");
862 * frescan_fna_network_bytes_to_budget()
864 * This operation converts a number of bytes into a temporal budget for
865 * a specific network. Network overheads are not included here but are
866 * considered internally when negotiating a specific contract.
868 * @param[in] resource_id The network
869 * @param[in] nbytes Number of bytes
870 * @param[out] budget The network budget for nbytes
873 * 0 if there are no errors \n
874 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
875 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
876 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
877 * a network accessible from the current processing node \n
878 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
882 int frescan_fna_network_bytes_to_budget
883 (const frsh_resource_id_t resource_id,
885 struct timespec *budget)
887 int number_of_packets;
889 if (budget == NULL || nbytes < 0) {
893 // we measure the budget in number of FRESCAN frames (8 bytes)
894 number_of_packets = nbytes / 8 + 1;
896 // we store the budget in number of packets instead of in time. We
897 // use a field in the timespec structure.
898 budget->tv_sec = number_of_packets;
900 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
901 "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
907 * frescan_fna_network_budget_to_bytes()
909 * This operation converts a temporal budget into a number of bytes for
910 * a specific network. Network overheads are not included.
912 * @param[in] resource_id The network
913 * @param[in] budget The network budget for nbytes
914 * @param[out] nbytes Number of bytes
917 * 0 if there are no errors \n
918 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
919 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
920 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
921 * a network accessible from the current processing node \n
922 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
923 * an invalid time value \n
926 int frescan_fna_network_budget_to_bytes
927 (const frsh_resource_id_t resource_id,
928 const struct timespec *budget,
931 int number_of_packets;
933 if (budget == NULL || nbytes == NULL) {
937 number_of_packets = budget->tv_sec;
939 *nbytes = number_of_packets * 8;
945 * frescan_fna_network_get_min_eff_budget()
947 * This operation gets the minimum effective budget for a network. Each message
948 * consumes a contracted budget in "chunks" (i.e: packets) that we call
949 * minimum effective budget.
951 * A negotiated contract, for N bytes in a period T, means that there is a
952 * virtual resource that reserves for the user:
954 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
956 * Note that if the user decides not to send these N bytes at once but, say,
957 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
958 * budget will become exhausted before sending all the bytes.
960 * @param[in] resource_id The network
961 * @param[out] budget The network budget
964 * 0 if there are no errors \n
965 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
966 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
967 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
968 * a network accessible from the current processing node \n
969 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
972 int frescan_fna_network_get_min_eff_budget
973 (const frsh_resource_id_t resource_id,
974 struct timespec *budget)
976 if (budget == NULL) {
985 // GLOBAL variable to install the network protocol in FRESCOR
987 fna_operations_t frescan_fna_operations = {
988 .fna_init = frescan_fna_init,
989 .fna_contract_negotiate = frescan_fna_contract_negotiate,
990 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
991 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
992 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
993 .fna_vres_destroy = frescan_fna_vres_destroy,
994 .fna_vres_get_contract = frescan_fna_vres_get_contract,
995 .fna_vres_get_usage = frescan_fna_vres_get_usage,
996 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
997 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
998 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
999 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1000 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1001 .fna_send_sync = frescan_fna_send_sync,
1002 .fna_send_async = frescan_fna_send_async,
1003 .fna_receive_sync = frescan_fna_receive_sync,
1004 .fna_receive_async = frescan_fna_receive_async,
1005 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1006 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1007 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1008 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1009 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1010 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1011 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget