1 //----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 by the FRESCOR consortium:
4 // Universidad de Cantabria, SPAIN
5 // University of York, UK
6 // Scuola Superiore Sant'Anna, ITALY
7 // Kaiserslautern University, GERMANY
8 // Univ. Politecnica Valencia, SPAIN
9 // Czech Technical University in Prague, CZECH REPUBLIC
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org
18 // The FRESCOR project (FP6/2005/IST/5-034026) is funded
19 // in part by the European Union Sixth Framework Programme
20 // The European Union is not liable of any use that may be
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // This file is part of FNA (Frescor Network Adaptation)
33 // FNA is free software; you can redistribute it and/or modify it
34 // under terms of the GNU General Public License as published by the
35 // Free Software Foundation; either version 2, or (at your option) any
36 // later version. FNA is distributed in the hope that it will be
37 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 // General Public License for more details. You should have received a
40 // copy of the GNU General Public License along with FNA; see file
41 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
42 // Cambridge, MA 02139, USA.
44 // As a special exception, including FNA header files in a file,
45 // instantiating FNA generics or templates, or linking other files
46 // with FNA objects to produce an executable application, does not
47 // by itself cause the resulting executable application to be covered
48 // by the GNU General Public License. This exception does not
49 // however invalidate any other reasons why the executable file might be
50 // covered by the GNU Public License.
51 // -----------------------------------------------------------------------
53 //==============================================
54 // ******** **** ** **
55 // **///// /**/** /** ****
56 // ** /**//** /** **//**
57 // ******* /** //** /** ** //**
58 // **//// /** //**/** **********
59 // ** /** //****/**//////**
60 // ** /** //***/** /**
63 // FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
64 //==============================================================
66 #include "frsh.h" /* frsh_resource_id_t, .. */
67 #include "frescan.h" /* frescan_init, ... */
68 #include "frescan_data.h" /* frescan_contract_t, ... */
69 #include "frescan_bandwidth_reservation.h" /* frescan_bwres_init, ... */
70 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
73 #include "frescan_debug.h" /* DEBUG, ERROR */
75 //////////////////////////////////////////////////////////////////////
77 //////////////////////////////////////////////////////////////////////
82 * This function will be hooked to the frsh_init function and it is
83 * intented to initialize the protocol and its structures.
85 * @param[in] resource_id The network we are referring to (a protocol
86 * could be able to handle several networks at the same time)
89 * 0 if there are no errors \n
90 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
91 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
92 * FNA_ERR_ALREADY_INITIALIZED:
93 * if the function has already been called before (with success) \n
96 int frescan_fna_init(const frsh_resource_id_t resource_id)
99 frescan_init_params_t init_params;
101 // TODO: resource_id must be relative or sth
102 // TODO: init_params must be configurable
103 init_params.net = (frescan_network_t)resource_id;
104 init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
105 init_params.tx_fp_max_prio = 10;
106 init_params.rx_num_of_channels = 10;
107 init_params.rx_channel_max_prio = NULL;
109 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
111 ret = frescan_init(&init_params);
112 if (ret != 0) ERROR ("could not init FRESCAN");
114 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
116 ret = frescan_bwres_init(init_params.net);
117 if (ret != 0) ERROR ("could not init BWRES");
122 ///////////////////////////////////////////////////////////////////
124 ///////////////////////////////////////////////////////////////////
127 * frescan_fna_contract_negotiate()
129 * The operation negotiates a contract and if accepted it will return
130 * a fna_vres_id_t. It will also check that the given contract_id is unique
131 * within the network.
133 * If the on-line admission test is enabled, it determines whether the
134 * contract can be admitted or not based on the current contracts
135 * established in the network. Then it creates the vres and
136 * recalculates all necessary parameters for the contracts already
137 * present in the system.
139 * This is a potentially blocking operation, it returns when the
140 * system has either rejected the contract, or admitted it and made it
143 * @param[in] resource_id The network we are referring to (a protocol
144 * could be able to handle several networks at the same time)
145 * @param[in] contract The contract parameters to negotiate
146 * @param[out] vres The internal virtual resource id
149 * 0 if there are no errors (in this case it also means contract accepted) \n
150 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
151 * FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
152 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
153 * FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
154 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
155 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
156 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
159 int frescan_fna_contract_negotiate
160 (const frsh_resource_id_t resource_id,
161 const frsh_contract_t *contract,
166 frescan_contract_t frescan_contract;
168 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
169 "frsh contract->frescan contract\n");
171 // TODO: budget is stored as number of can frames in tv_sec
172 frescan_contract.min_values.budget = contract->budget_min.tv_sec;
173 frescan_contract.min_values.period = contract->period_max;
175 frescan_contract.max_values.budget = contract->budget_max.tv_sec;
176 frescan_contract.max_values.period = contract->period_min;
178 frescan_contract.prio = contract->preemption_level;
180 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
181 accepted = frescan_bwres_negotiate((frescan_network_t)resource_id,
183 &ss); // TODO: associate the contract with the ss
186 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
187 *vres = (fna_vres_id_t)ss;
189 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
196 * frescan_fna_contract_renegotiate_sync()
198 * The operation renegotiates a contract for an existing vres. If
199 * the on-line admission test is enabled it determines whether the
200 * contract can be admitted or not based on the current contracts
201 * established in the system. If it cannot be admitted, the old
202 * contract remains in effect and an error is returned. If it can be
203 * admitted, it recalculates all necessary parameters for the
204 * contracts already present in the system and returns zero. This is a
205 * potentially blocking operation; it returns when the system has
206 * either rejected the new contract, or admitted it and made it
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
215 * 0 if there are no errors (in this case it also means contract accepted) \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_CONTRACT_REJECTED: if the contract is not accepted \n
220 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
221 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
222 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
225 int frescan_fna_contract_renegotiate_sync
226 (const frsh_resource_id_t resource_id,
227 const fna_vres_id_t vres,
228 const frsh_contract_t *new_contract)
230 ERROR("not implemented\n");
235 * frescan_fna_contract_renegotiate_async()
237 * The operation enqueues a renegotiate operation for an existing
238 * vres, and returns immediately. The renegotiate operation is
239 * performed asynchronously, as soon as it is practical; meanwhile the
240 * system operation will continue normally. When the renegotiation is
241 * made, if the on-line admission test is enabled it determines
242 * whether the contract can be admitted or not based on the current
243 * contracts established in the system. If it cannot be admitted, the
244 * old contract remains in effect. If it can be admitted, it
245 * recalculates all necessary parameters for the contracts already
246 * present in the system.
248 * When the operation is completed, notification is made to the
249 * caller, if requested, via a signal. The status of the operation (in
250 * progress, admitted, rejected) can be checked with the
251 * frsh_vres_get_renegotiation_status() operation. The argument
252 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
253 * signal value and in this case signal_info is to be sent with the signal.
255 * @param[in] resource_id The network we are referring to (a protocol
256 * could be able to handle several networks at the same time)
257 * @param[in] vres The internal virtual resource id to renegotiate
258 * @param[in] new_contract The new contract
259 * @param[in] signal_to_notify Signal number to use to notify vres of
260 * the negotiation result. If FRSH_NULL_SIGNAL, no signal will be raised.
261 * @param[in] signal_info: Associated info that will come with the signal.
262 * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
265 * 0 if there are no errors \n
266 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
267 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
268 * FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
269 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
270 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
271 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
272 * NULL nor a valid POSIX signal \n
275 int frescan_fna_contract_renegotiate_async
276 (const frsh_resource_id_t resource_id,
277 const fna_vres_id_t vres,
278 const frsh_contract_t *new_contract,
279 frsh_signal_t signal_to_notify,
280 frsh_signal_info_t signal_info)
282 ERROR("not implemented\n");
287 * frescan_fna_vres_get_renegotiation_status()
289 * The operation reports on the status of the last renegotiation
290 * operation enqueued for the specified vres. It is callable even
291 * after notification of the completion of such operation, if
294 * If the vres is not and has not been involved in any of the
295 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
296 * operations, the status returned is FNA_NOT_REQUESTED
298 * @param[in] resource_id The network we are referring to (a protocol
299 * could be able to handle several networks at the same time)
300 * @param[in] vres The internal virtual resource id we want the status from
301 * @param[in] renegotiation_status The status of the last renegotiation on
302 * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
303 * FRSH_RS_NOT_REQUESTED)
306 * 0 if there are no errors \n
307 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
308 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
309 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
310 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
311 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
314 int frescan_fna_vres_get_renegotiation_status
315 (const frsh_resource_id_t resource_id,
316 const fna_vres_id_t vres,
317 frsh_renegotiation_status_t *renegotiation_status)
319 ERROR("not implemented\n");
324 * frescan_fna_vres_destroy()
326 * The operation eliminates the specified vres
327 * and recalculates all necessary parameters for the contracts
328 * remaining in the system. This is a potentially blocking operation;
329 * it returns when the system has made the changes effective.
331 * @param[in] resource_id The network we are referring to (a protocol
332 * could be able to handle several networks at the same time)
333 * @param[in] vres The internal virtual resource id to destroy
336 * 0 if there are no errors \n
337 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
338 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
339 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
340 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
341 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
344 int frescan_fna_vres_destroy
345 (const frsh_resource_id_t resource_id,
346 const fna_vres_id_t vres)
348 ERROR("not implemented\n");
353 * frescan_fna_vres_get_contract()
355 * This operation stores the contract parameters currently associated
356 * with the specified vres in the variable pointed to by
357 * contract. It returns an error if the vres_id is not recognised.
359 * @param[in] resource_id The network we are referring to (a protocol
360 * could be able to handle several networks at the same time)
361 * @param[in] vres The internal virtual resource id
362 * @param[out] contract The contract parameters that we want
365 * 0 if there are no errors \n
366 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
367 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
368 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
369 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
370 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
373 int frescan_fna_vres_get_contract
374 (const frsh_resource_id_t resource_id,
375 const fna_vres_id_t vres,
376 frsh_contract_t *contract)
378 ERROR("not implemented\n");
383 * frescan_fna_vres_get_usage()
385 * This function gets the execution time spent by all messages that have been
386 * sent through the specified vres.
388 * @param[in] resource_id The network we are referring to (a protocol
389 * could be able to handle several networks at the same time)
390 * @param[in] vres The internal virtual resource id
391 * @param[out] usage Execution time spent by this vres
394 * 0 if there are no errors \n
395 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
396 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
397 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
398 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
399 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
402 int frescan_fna_vres_get_usage
403 (const frsh_resource_id_t resource_id,
404 const fna_vres_id_t vres,
405 struct timespec *usage)
407 ERROR("not implemented\n");
412 * frescan_fna_vres_get_remaining_budget()
414 * This function stores in the variable pointed to by budget the
415 * remaining execution-time budget associated with the specified
416 * vres in the present period.
418 * @param[in] resource_id The network we are referring to (a protocol
419 * could be able to handle several networks at the same time)
420 * @param[in] vres The internal virtual resource id
421 * @param[out] remaining_budget The remaining budget for this period
424 * 0 if there are no errors \n
425 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
426 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
427 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
428 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
429 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
432 int frescan_fna_vres_get_remaining_budget
433 (const frsh_resource_id_t resource_id,
434 const fna_vres_id_t vres,
435 struct timespec *remaining_budget)
437 ERROR("not implemented\n");
442 * frescan_fna_vres_get_budget_and_period()
444 * This function gets the budget and period associated with the specified vres
445 * for each period. If one of these pointers is NULL, the corresponding
446 * information is not stored.
448 * @param[in] resource_id The network we are referring to (a protocol
449 * could be able to handle several networks at the same time)
450 * @param[in] vres The internal virtual resource id
451 * @param[out] budget The budget associated to vres
452 * @param[out] period The period associated to vres
455 * 0 if there are no errors \n
456 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
457 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
458 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
459 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
460 * FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
463 int frescan_fna_vres_get_budget_and_period
464 (const frsh_resource_id_t resource_id,
465 const fna_vres_id_t vres,
466 struct timespec *budget,
467 struct timespec *period)
469 ERROR("not implemented\n");
475 ///////////////////////////////////////////////////////////////////
476 // SPARE CAPACITY FUNCIONS
477 ///////////////////////////////////////////////////////////////////
480 * @defgroup fnaspare FNA Spare Capacity
483 * The following functions are used to get spare capacity data
489 * frescan_fna_resource_get_capacity()
491 * This operation gets the spare capacity currently assigned to a importance
492 * level. If we divide this value by UINT32_MAX we will get the network
493 * utilization associated to the spare capacity of a importance level.
495 * The following is typically in stdint.h: \n
496 * - typedef unsigned int uint32_t; \n
497 * - # define UINT32_MAX (4294967295U) \n
499 * @param[in] resource_id The network we are referring to (a protocol
500 * could be able to handle several networks at the same time)
501 * @param[in] importance The importance we want the capacity of
502 * @param[out] capacity The spare capacity for that importance level
505 * 0 if there are no errors \n
506 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
507 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
508 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
509 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
512 int frescan_fna_resource_get_capacity
513 (const frsh_resource_id_t resource_id,
514 const int importance,
517 ERROR("not implemented\n");
522 * frescan_fna_resource_get_total_weight()
524 * This function gets the sum of the weight parameters for all vres in a
525 * network of an importance level.
527 * @param[in] resource_id The network we are referring to (a protocol
528 * could be able to handle several networks at the same time)
529 * @param[in] importance The importance we want the total weight of
530 * @param[out] total_weight The total weight for that importance level
533 * 0 if there are no errors \n
534 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
535 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
536 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
537 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
540 int frescan_fna_resource_get_total_weight
541 (const frsh_resource_id_t resource_id,
542 const int importance,
545 ERROR("not implemented\n");
550 * frescan_fna_vres_decrease_capacity()
552 * This function allows to ask for less budget and period than what we
553 * received. The request must be compatible with the rest of contract
554 * parameters of the vres. If we want to recover the released capacity
555 * we will need to renegotiate.
557 * @param[in] resource_id The network we are referring to (a protocol
558 * could be able to handle several networks at the same time)
559 * @param[in] vres The internal virtual resource id
560 * @param[in] new_budget The new_budget
561 * @param[in] new_period The new Period
564 * 0 if there are no errors \n
565 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
566 * FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
567 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
568 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
569 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
570 * FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
574 int frescan_fna_vres_decrease_capacity
575 (const frsh_resource_id_t resource_id,
576 const fna_vres_id_t vres,
577 const struct timespec new_budget,
578 const struct timespec new_period)
580 ERROR("not implemented\n");
584 ///////////////////////////////////////////////////////////////////
585 // SEND RECEIVE OPERATIONS
586 ///////////////////////////////////////////////////////////////////
589 * frescan_fna_send_sync()
591 * Similar to previous function but now the sending thread gets blocked
592 * until the message is already sent to the network.
594 * @param[in] endpoint The send endpoint we are sending through. It must
595 * be bound to a virtual resource (resource_id is in the endpoint).
596 * @param[in] msg The message we want to send
597 * @param[in] size The size in bytes of the message
600 * 0 if there are no errors \n
601 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
602 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
603 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
604 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
605 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
606 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
607 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
608 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
611 int frescan_fna_send_sync
612 (const fna_endpoint_data_t *endpoint,
616 ERROR("not implemented\n");
621 * frescan_fna_send_async()
623 * This operation sends a message stored in msg and of length size
624 * through the given send endpoint. The operation is non-blocking and
625 * returns immediately.
627 * @param[in] endpoint The send endpoint we are sending through. It must
628 * be bound to a virtual resource (resource_id is in the endpoint).
629 * @param[in] msg The message we want to send
630 * @param[in] size The size in bytes of the message
633 * 0 if there are no errors \n
634 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
635 * FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
636 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
637 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
638 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
639 * FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
640 * FNA_ERR_BUFFER_FULL: if the message has been discarded because
641 * the queue is full (and does not have the policy FNA_QP_OLDEST) \n
644 int frescan_fna_send_async
645 (const fna_endpoint_data_t *endpoint,
650 frescan_send_params_t params;
652 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
653 "net:%u dest:%u chan:%u size:%u ss:%u\n",
654 endpoint->resource_id, endpoint->destination,
655 endpoint->stream_id, size, endpoint->vres);
657 params.net = (frescan_network_t)endpoint->resource_id;
658 params.to = (frescan_node_t)endpoint->destination;
659 params.channel = (frescan_channel_t)endpoint->stream_id;
660 params.flags = FRESCAN_SS | FRESCAN_ASYNC;
661 params.ss = endpoint->vres;
663 ret = frescan_send(¶ms, (uint8_t *)msg, size);
665 ERROR ("could not send message\n");
673 * frescan_fna_receive_sync()
675 * This operation is used to receive messages from the network with a
676 * blocking behavior (if there are no messages this operation blocks
677 * the calling thread).
679 * When a message is available, it is copied to buffer (up to its size).
680 * The number of bytes copied is returned in received_bytes. The rest
681 * of the bytes of that message will be lost or not depending on the
682 * protocol (FNA_ERR_NO_SPACE will be returned if it is).
684 * The function fails with FNA_ERR_NO_SPACE if the buffersize is
685 * too small for the message received. In this case the message is
688 * Messages arriving at a receiver buffer that is full will be handled
689 * according to the queueing policy of the endpoint (overwrite oldest,
692 * @param[in] endpoint The receive endpoint we are receiving from.
693 * (resource_id is in the endpoint).
694 * @param[out] buffer Buffer for storing the received message
695 * @param[in] buffer_size The size in bytes of this buffer
696 * @param[out] received_bytes The actual number of received bytes
697 * @param[out] from Address of the sender node
700 * 0 if there are no errors \n
701 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
702 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
703 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
704 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
705 * FNA_ERR_NO_SPACE: if the message size is bigger than the
706 * provided buffer. \n
709 int frescan_fna_receive_sync
710 (const fna_endpoint_data_t *endpoint,
712 const size_t buffer_size,
713 size_t *received_bytes,
714 frsh_network_address_t *from)
717 frescan_recv_params_t params;
718 frescan_node_t frescan_from;
721 params.net = (frescan_network_t)endpoint->resource_id;
722 params.channel = (frescan_channel_t)endpoint->stream_id;
723 params.flags = FRESCAN_SYNC;
725 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
726 "net:%u chan:%u size:%u\n",
727 endpoint->resource_id, endpoint->stream_id, buffer_size);
729 ret = frescan_recv(¶ms, (uint8_t *)buffer, buffer_size,
730 received_bytes, &frescan_from, &prio);
733 ERROR ("error while receiving message");
737 *from = (frsh_network_address_t)frescan_from;
739 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
740 "msg received, from:%u bytes:%u prio:%u\n",
741 *from, *received_bytes, prio);
747 * frescan_fna_receive_async()
749 * This operation is similar to the previous one but it works in a non
750 * blocking (asynchronous) fashion. If no message is available it
751 * returns with error FNA_NO_MESSAGE.
753 * @param[in] endpoint The receive endpoint we are receiving from.
754 * (resource_id is in the endpoint).
755 * @param[out] buffer Buffer for storing the received message
756 * @param[in] buffer_size The size in bytes of this buffer
757 * @param[out] received_bytes The actual number of received bytes
758 * @param[out] from Address of the sender node
761 * 0 if there are no errors \n
762 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
763 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
764 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
765 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
766 * FNA_ERR_NO_SPACE: if the message size is bigger than the
767 * provided buffer. \n
768 * FNA_NO_MESSAGE: if no messages are available in the queue. \n
771 int frescan_fna_receive_async
772 (const fna_endpoint_data_t *endpoint,
774 const size_t buffer_size,
775 size_t *received_bytes,
776 frsh_network_address_t *from)
778 ERROR("not implemented\n");
783 * frescan_fna_send_endpoint_get_status()
785 * This function tells the number of messages still pending in the
786 * endpoint queue, whether the network is up or down with some
787 * optional information which is protocol_dependent.
789 * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
790 * @param[out] number_of_pending_messages The number of pending messages
791 * @param[out] network_status How is the network (up, down..)
792 * @param[out] protocol_status Protocol dependent status info
795 * 0 if there are no errors \n
796 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
797 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
798 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
799 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
802 int frescan_fna_send_endpoint_get_status
803 (const fna_endpoint_data_t *endpoint,
804 int *number_of_pending_messages,
805 frsh_endpoint_network_status_t *network_status,
806 frsh_protocol_status_t *protocol_status)
808 ERROR("not implemented\n");
813 * frescan_fna_receive_endpoint_created()
815 * This operation is a called from frsh_receive_endpoint_create with a
816 * receive_endpoint structure already filled.
818 * Receiving endpoints are not bound to any network vres, this is
819 * because don't originate any traffic.
821 * @param[in] endpoint the endpoint object.
824 * 0 if there are no errors \n
825 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
826 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
827 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
828 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
830 int frescan_fna_receive_endpoint_created
831 (fna_endpoint_data_t *endpoint)
833 DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
838 * frescan_fna_receive_endpoint_get_pending_messages
840 * This function tells the number of messages still pending in the
841 * endpoint queue, whether the network is up or down and some optional
842 * information which is protocol dependent.
844 * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
845 * @param[out] number_of_pending_messages The number of pending messages
846 * @param[out] network_status How is the network (up, down..)
847 * @param[out] protocol_status Protocol dependent status info
850 * 0 if there are no errors \n
851 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
852 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
853 * FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
854 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
857 int frescan_fna_receive_endpoint_get_status
858 (const fna_endpoint_data_t *endpoint,
859 int *number_of_pending_messages,
860 frsh_endpoint_network_status_t *network_status,
861 frsh_protocol_status_t *protocol_status)
863 ERROR("not implemented\n");
867 //////////////////////////////////////////////////////////////////////
868 // NETWORK CONFIGURATION FUNCTIONS
869 //////////////////////////////////////////////////////////////////////
872 * frescan_fna_network_get_max_message_size()
874 * This operation gives the maximum number of bytes that can be sent
875 * at a time through the send function when using the network designated by
876 * 'resource_id' and sending it to 'destination'.
878 * If the application needs to send bigger messages it will have to
881 * Some protocols, like IP, are capable of sending large messages
882 * (and use fragmentation internally) but other protocols don't.
884 * @param[in] resource_id The network we want the tx time from.
885 * @param[in] destination The destination address
886 * @param[out] max_size The maximum number of bytes for each message
889 * 0 if there are no errors \n
890 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
891 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
892 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
893 * a network accessible from the current processing node \n
894 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
898 int frescan_fna_network_get_max_message_size
899 (const frsh_resource_id_t resource_id,
900 const frsh_network_address_t destination,
903 ERROR("not implemented\n");
908 * frescan_fna_network_bytes_to_budget()
910 * This operation converts a number of bytes into a temporal budget for
911 * a specific network. Network overheads are not included here but are
912 * considered internally when negotiating a specific contract.
914 * @param[in] resource_id The network
915 * @param[in] nbytes Number of bytes
916 * @param[out] budget The network budget for nbytes
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 nbytes is less
928 int frescan_fna_network_bytes_to_budget
929 (const frsh_resource_id_t resource_id,
931 struct timespec *budget)
933 int number_of_packets;
935 if (budget == NULL || nbytes < 0) {
939 // we measure the budget in number of FRESCAN frames (8 bytes)
940 number_of_packets = nbytes / 8 + 1;
942 // we store the budget in number of packets instead of in time. We
943 // use a field in the timespec structure.
944 budget->tv_sec = number_of_packets;
946 DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
947 "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
953 * frescan_fna_network_budget_to_bytes()
955 * This operation converts a temporal budget into a number of bytes for
956 * a specific network. Network overheads are not included.
958 * @param[in] resource_id The network
959 * @param[in] budget The network budget for nbytes
960 * @param[out] nbytes Number of bytes
963 * 0 if there are no errors \n
964 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
965 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
966 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
967 * a network accessible from the current processing node \n
968 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
969 * an invalid time value \n
972 int frescan_fna_network_budget_to_bytes
973 (const frsh_resource_id_t resource_id,
974 const struct timespec *budget,
977 int number_of_packets;
979 if (budget == NULL || nbytes == NULL) {
983 number_of_packets = budget->tv_sec;
985 *nbytes = number_of_packets * 8;
991 * frescan_fna_network_get_min_eff_budget()
993 * This operation gets the minimum effective budget for a network. Each message
994 * consumes a contracted budget in "chunks" (i.e: packets) that we call
995 * minimum effective budget.
997 * A negotiated contract, for N bytes in a period T, means that there is a
998 * virtual resource that reserves for the user:
1000 * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1002 * Note that if the user decides not to send these N bytes at once but, say,
1003 * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1004 * budget will become exhausted before sending all the bytes.
1006 * @param[in] resource_id The network
1007 * @param[out] budget The network budget
1010 * 0 if there are no errors \n
1011 * FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1012 * FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1013 * FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1014 * a network accessible from the current processing node \n
1015 * FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1018 int frescan_fna_network_get_min_eff_budget
1019 (const frsh_resource_id_t resource_id,
1020 struct timespec *budget)
1022 if (budget == NULL) {
1031 // GLOBAL variable to install the network protocol in FRESCOR
1033 fna_operations_t frescan_fna_operations = {
1034 .fna_init = frescan_fna_init,
1035 .fna_contract_negotiate = frescan_fna_contract_negotiate,
1036 .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1037 .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1038 .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1039 .fna_vres_destroy = frescan_fna_vres_destroy,
1040 .fna_vres_get_contract = frescan_fna_vres_get_contract,
1041 .fna_vres_get_usage = frescan_fna_vres_get_usage,
1042 .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1043 .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1044 .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1045 .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1046 .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1047 .fna_send_sync = frescan_fna_send_sync,
1048 .fna_send_async = frescan_fna_send_async,
1049 .fna_receive_sync = frescan_fna_receive_sync,
1050 .fna_receive_async = frescan_fna_receive_async,
1051 .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1052 .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1053 .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1054 .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1055 .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1056 .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1057 .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget