]> rtime.felk.cvut.cz Git - frescor/fna.git/blob - src_frescan/frescan_bwres_fna.c
improve a bit some error messages
[frescor/fna.git] / src_frescan / frescan_bwres_fna.c
1 /*!
2  * @file frescan_bwres_fna.c
3  *
4  * @brief FRESCAN bandwidth reservation layer: FNA hooks
5  *
6  * This module contains hooks to integrate the FRESCAN protocol in FRSH
7  *
8  * @version 0.01
9  *
10  * @date 1-Apr-2008
11  *
12  * @author Daniel Sangorrin <daniel.sangorrin@unican.es>
13  *
14  * @license
15  *
16  * -----------------------------------------------------------------------
17  *  Copyright (C) 2006 - 2008 FRESCOR consortium partners:
18  *
19  *    Universidad de Cantabria,              SPAIN
20  *    University of York,                    UK
21  *    Scuola Superiore Sant'Anna,            ITALY
22  *    Kaiserslautern University,             GERMANY
23  *    Univ. Politécnica  Valencia,           SPAIN
24  *    Czech Technical University in Prague,  CZECH REPUBLIC
25  *    ENEA                                   SWEDEN
26  *    Thales Communication S.A.              FRANCE
27  *    Visual Tools S.A.                      SPAIN
28  *    Rapita Systems Ltd                     UK
29  *    Evidence                               ITALY
30  *
31  *    See http://www.frescor.org for a link to partners' websites
32  *
33  *           FRESCOR project (FP6/2005/IST/5-034026) is funded
34  *        in part by the European Union Sixth Framework Programme
35  *        The European Union is not liable of any use that may be
36  *        made of this code.
37  *
38  *  This file is part of FRESCAN
39  *
40  *  FRESCAN is free software; you can  redistribute it and/or  modify
41  *  it under the terms of  the GNU General Public License as published by
42  *  the Free Software Foundation;  either  version 2, or (at  your option)
43  *  any later version.
44  *
45  *  FRESCAN  is distributed  in  the hope  that  it  will  be useful,  but
46  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
47  *  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
48  *  General Public License for more details.
49  *
50  *  You should have  received a  copy of  the  GNU  General Public License
51  *  distributed  with  FRESCAN;  see file COPYING.   If not,  write to the
52  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
53  *  02111-1307, USA.
54  *
55  * As a special exception, including FRESCAN header files in a file,
56  * instantiating FRESCAN generics or templates, or linking other files
57  * with FRESCAN objects to produce an executable application, does not
58  * by itself cause the resulting executable application to be covered
59  * by the GNU General Public License. This exception does not
60  * however invalidate any other reasons why the executable file might be
61  * covered by the GNU Public License.
62  * -----------------------------------------------------------------------
63  *
64  */
65
66 #include <math.h> /* ceil */
67
68 #include "frsh.h" /* frsh_resource_id_t, .. */
69 #include "frescan.h" /* frescan_init, ... */
70 #include "frescan_bwres.h" /* frescan_bwres_init, ... */
71 #include "frescan_types.h"
72 #include "frescan_config.h"
73 #include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
74 #include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
75 #include "frescan_servers.h"
76
77 //////////////////////////////////////////////////////////////////////
78 //           INITIALIZATION
79 //////////////////////////////////////////////////////////////////////
80
81 /**
82  * frescan_fna_init()
83  *
84  * This function will be hooked to the frsh_init function and it is
85  * intented to initialize the protocol and its structures.
86  *
87  * @param[in]  resource_id The network we are referring to (a protocol
88  * could be able to handle several networks at the same time)
89  *
90  * @return
91  *   0 if there are no errors \n
92  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
93  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
94  *   FNA_ERR_ALREADY_INITIALIZED:
95  *      if the function has already been called before (with success) \n
96  *
97  **/
98 int frescan_fna_init(const frsh_resource_id_t resource_id)
99 {
100         int ret;
101         frescan_init_params_t init_params;
102
103         init_params.net = resource_id - FRESCAN_BWRES_FNA_NET_BASE;
104         init_params.node = FRESCAN_BWRES_FNA_LOCAL_NODE;
105         init_params.tx_fp_max_prio = FRESCAN_BWRES_TX_FP_MX_PRIO;
106         init_params.rx_num_of_channels = FRESCAN_BWRES_RX_NUM_CHANNELS;
107         init_params.rx_channel_max_prio = FRESCAN_BWRES_RX_CHAN_MX_PRIO;
108
109         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
110               "Initializing FRESCAN FNA node%u\n", init_params.node);
111
112         ret = frescan_init(&init_params);
113         if (ret != 0) {
114                 FRESCAN_ERROR ("could not init FRESCAN\n");
115                 return ret;
116         }
117
118         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
119
120         ret = frescan_bwres_init(init_params.net);
121         if (ret != 0) {
122                 FRESCAN_ERROR ("could not init BWRES\n");
123                 return ret;
124         }
125
126         return 0;
127 }
128
129 ///////////////////////////////////////////////////////////////////
130 //           VIRTUAL RESOURCES
131 ///////////////////////////////////////////////////////////////////
132
133 int frescan_fna_group_change_mode_sync
134                 (const frsh_resource_id_t     resource_id,
135                  const frsh_contracts_group_t *contracts_to_neg,
136                  const frsh_contracts_group_t *contracts_to_reneg,
137                  const fna_vres_group_t       *vres_to_reneg,
138                  const fna_vres_group_t       *vres_to_cancel,
139                  fna_vres_group_t             *new_vres)
140 {
141         int ret, i;
142         bool accepted;
143         frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
144
145         // convert fna_vres to ss
146         if (vres_to_reneg == NULL) {
147                 ss_to_reneg.size = 0;
148         } else {
149                 ss_to_reneg.size = vres_to_reneg->size;
150                 if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
151                         FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
152                         return -1;
153                 }
154
155                 for(i=0; i<ss_to_reneg.size; i++) {
156                         ss_to_reneg.ss[i] =
157                                         (frescan_ss_t)vres_to_reneg->vres[i];
158                 }
159         }
160
161         if (vres_to_cancel == NULL) {
162                 ss_to_cancel.size = 0;
163         } else {
164                 ss_to_cancel.size = vres_to_cancel->size;
165                 if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
166                         FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
167                         return -1;
168                 }
169
170                 for(i=0; i<ss_to_cancel.size; i++) {
171                         ss_to_cancel.ss[i] =
172                                         (frescan_ss_t)vres_to_cancel->vres[i];
173                 }
174         }
175
176         if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
177                 FRESCAN_ERROR("new_vres is NULL\n");
178                 return -1;
179         }
180
181         // negotiate
182         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
183               "calling frescan_bwres_group_change_mode_sync\n");
184
185         ret = frescan_bwres_group_change_mode_sync
186                                         ((frescan_network_t)resource_id,
187                                          contracts_to_neg,
188                                          contracts_to_reneg,
189                                          &ss_to_reneg,
190                                          &ss_to_cancel,
191                                          &ss_new,
192                                          &accepted);
193         if (ret != 0) return -1;
194
195         if (accepted == false) {
196                 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
197                 return -1; // TODO: change to constant FNA_REJECTED
198         }
199
200         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
201         // convert new ss to fna_vres
202         if (contracts_to_neg != NULL) {
203                 new_vres->size = ss_new.size;
204                 DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
205                       "new_vres->size:%d\n", new_vres->size);
206                 for(i=0; i<new_vres->size; i++) {
207                         new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
208                         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
209                               "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
210                 }
211         }
212
213         return 0;
214 }
215
216 /**
217  * frescan_fna_contract_negotiate()
218  *
219  * The operation negotiates a contract and if accepted it will return
220  * a fna_vres_id_t. It will also check that the given contract_id is unique
221  * within the network.
222  *
223  * If the on-line admission test is enabled, it determines whether the
224  * contract can be admitted or not based on the current contracts
225  * established in the network. Then it creates the vres and
226  * recalculates all necessary parameters for the contracts already
227  * present in the system.
228  *
229  * This is a potentially blocking operation, it returns when the
230  * system has either rejected the contract, or admitted it and made it
231  * effective.
232  *
233  * @param[in] resource_id The network we are referring to (a protocol
234  * could be able to handle several networks at the same time)
235  * @param[in] contract  The contract parameters to negotiate
236  * @param[out] vres The internal virtual resource id
237  *
238  * @return
239  *   0 if there are no errors (in this case it also means contract accepted) \n
240  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
241  *   FNA_ERR_TOO_MANY_VRES: if there is no space for more vres \n
242  *   FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
243  *   FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
244  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
245  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
246  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
247  *
248  **/
249 int frescan_fna_contract_negotiate
250                 (const frsh_resource_id_t resource_id,
251                  const frsh_contract_t *contract,
252                  fna_vres_id_t *vres)
253 {
254         int ret;
255         frsh_contracts_group_t contracts_to_neg;
256         fna_vres_group_t       new_vres;
257
258         contracts_to_neg.size = 1;
259         contracts_to_neg.contracts[0] = *contract;
260
261         ret = frescan_fna_group_change_mode_sync
262                 (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
263         if (ret != 0) return ret;
264
265         *vres = new_vres.vres[0];
266         return 0;
267 }
268
269 /**
270  * frescan_fna_contract_renegotiate_sync()
271  *
272  * The operation renegotiates a contract for an existing vres. If
273  * the on-line admission test is enabled it determines whether the
274  * contract can be admitted or not based on the current contracts
275  * established in the system. If it cannot be admitted, the old
276  * contract remains in effect and an error is returned. If it can be
277  * admitted, it recalculates all necessary parameters for the
278  * contracts already present in the system and returns zero. This is a
279  * potentially blocking operation; it returns when the system has
280  * either rejected the new contract, or admitted it and made it
281  * effective.
282  *
283  * @param[in] resource_id The network we are referring to (a protocol
284  * could be able to handle several networks at the same time)
285  * @param[in] vres The internal virtual resource id to renegotiate
286  * @param[in] new_contract The new contract
287  *
288  *  @return
289  *   0 if there are no errors (in this case it also means contract accepted) \n
290  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
291  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
292  *   FNA_ERR_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
293  *   FNA_ERR_CONTRACT_REJECTED: if the contract is not accepted \n
294  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
295  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
296  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
297  *
298  **/
299 int frescan_fna_contract_renegotiate_sync
300                 (const frsh_resource_id_t resource_id,
301                  const fna_vres_id_t vres,
302                  const frsh_contract_t *new_contract)
303 {
304         frsh_contracts_group_t contracts_to_reneg;
305         fna_vres_group_t       vres_to_reneg;
306
307         contracts_to_reneg.size = 1;
308         contracts_to_reneg.contracts[0] = *new_contract;
309         vres_to_reneg.size = 1;
310         vres_to_reneg.vres[0] = vres;
311
312         return frescan_fna_group_change_mode_sync
313                                 (resource_id, NULL, &contracts_to_reneg,
314                                  &vres_to_reneg, NULL, NULL);
315 }
316
317 /**
318  * frescan_fna_contract_renegotiate_async()
319  *
320  * The operation enqueues a renegotiate operation for an existing
321  * vres, and returns immediately. The renegotiate operation is
322  * performed asynchronously, as soon as it is practical; meanwhile the
323  * system operation will continue normally. When the renegotiation is
324  * made, if the on-line admission test is enabled it determines
325  * whether the contract can be admitted or not based on the current
326  * contracts established in the system. If it cannot be admitted, the
327  * old contract remains in effect. If it can be admitted, it
328  * recalculates all necessary parameters for the contracts already
329  * present in the system.
330  *
331  * When the operation is completed, notification is made to the
332  * caller, if requested, via a signal. The status of the operation (in
333  * progress, admitted, rejected) can be checked with the
334  * frsh_vres_get_renegotiation_status() operation.  The argument
335  * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
336  * signal value and in this case signal_info is to be sent with the signal.
337  *
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 to renegotiate
341  * @param[in] new_contract The new contract
342  * @param[in] signal_to_notify  Signal number to use to notify vres of
343  * the negotiation result. If FRSH_NULL_SIGNAL,  no signal will be raised.
344  * @param[in] signal_info: Associated info that will come with the signal.
345  * This parameter will be ignored if signal_to_notify == FRSH_NULL_SIGNAL.
346  *
347  * @return
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_CONTRACT_ID_ALREADY_EXISTS: contract_id is not unique \n
352  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
353  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
354  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL, or sig_notify is neither
355  *      NULL nor a valid POSIX signal \n
356  *
357  **/
358 int frescan_fna_contract_renegotiate_async
359                 (const frsh_resource_id_t resource_id,
360                  const fna_vres_id_t vres,
361                  const frsh_contract_t *new_contract,
362                  frsh_signal_t signal_to_notify,
363                  frsh_signal_info_t signal_info)
364 {
365         FRESCAN_ERROR("not implemented\n");
366         return -1;
367 }
368
369 /**
370  * frescan_fna_vres_get_renegotiation_status()
371  *
372  * The operation reports on the status of the last renegotiation
373  * operation enqueued for the specified vres. It is callable even
374  * after notification of the completion of such operation, if
375  * requested.
376  *
377  * If the vres is not and has not been involved in any of the
378  * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
379  * operations, the status returned is FNA_NOT_REQUESTED
380  *
381  * @param[in] resource_id The network we are referring to (a protocol
382  * could be able to handle several networks at the same time)
383  * @param[in] vres The internal virtual resource id we want the status from
384  * @param[in] renegotiation_status The status of the last renegotiation on
385  * vres (FRSH_RS_IN_PROGRESS, FRSH_RS_REJECTED, FRSH_RS_ADMITTED,
386  * FRSH_RS_NOT_REQUESTED)
387  *
388  * @return
389  *   0 if there are no errors \n
390  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
391  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
392  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
393  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
394  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
395  *
396  **/
397 int frescan_fna_vres_get_renegotiation_status
398                 (const frsh_resource_id_t resource_id,
399                  const fna_vres_id_t vres,
400                  frsh_renegotiation_status_t *renegotiation_status)
401 {
402         FRESCAN_ERROR("not implemented\n");
403         return -1;
404 }
405
406 /**
407  * frescan_fna_vres_destroy()
408  *
409  * The operation eliminates the specified vres
410  * and recalculates all necessary parameters for the contracts
411  * remaining in the system. This is a potentially blocking operation;
412  * it returns when the system has made the changes effective.
413  *
414  * @param[in] resource_id The network we are referring to (a protocol
415  * could be able to handle several networks at the same time)
416  * @param[in] vres The internal virtual resource id to destroy
417  *
418  * @return
419  *   0 if there are no errors \n
420  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
421  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
422  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
423  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
424  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
425  *
426  **/
427 int frescan_fna_vres_destroy
428                 (const frsh_resource_id_t resource_id,
429                  const fna_vres_id_t vres)
430 {
431         fna_vres_group_t  vres_to_cancel;
432
433         vres_to_cancel.size = 1;
434         vres_to_cancel.vres[0] = vres;
435
436         return frescan_fna_group_change_mode_sync
437                        (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
438 }
439
440 /**
441  * frescan_fna_vres_get_contract()
442  *
443  * This operation stores the contract parameters currently associated
444  * with the specified vres in the variable pointed to by
445  * contract. It returns an error if the vres_id is not recognised.
446  *
447  * @param[in] resource_id The network we are referring to (a protocol
448  * could be able to handle several networks at the same time)
449  * @param[in] vres The internal virtual resource id
450  * @param[out] contract  The contract parameters that we want
451  *
452  * @return
453  *   0 if there are no errors \n
454  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
455  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
456  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
457  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
458  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
459  *
460  **/
461 int frescan_fna_vres_get_contract
462                 (const frsh_resource_id_t resource_id,
463                  const fna_vres_id_t vres,
464                  frsh_contract_t *contract)
465 {
466         FRESCAN_ERROR("not implemented\n");
467         return -1;
468 }
469
470 /**
471  * frescan_fna_vres_get_usage()
472  *
473  * This function gets the execution time spent by all messages that have been
474  * sent through the specified vres.
475  *
476  * @param[in] resource_id The network we are referring to (a protocol
477  * could be able to handle several networks at the same time)
478  * @param[in] vres The internal virtual resource id
479  * @param[out] usage  Execution time spent by this vres
480  *
481  * @return
482  *   0 if there are no errors \n
483  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
484  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \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
488  *
489  **/
490 int frescan_fna_vres_get_usage
491                 (const frsh_resource_id_t resource_id,
492                  const fna_vres_id_t vres,
493                  struct timespec *usage)
494 {
495         FRESCAN_ERROR("not implemented\n");
496         return -1;
497 }
498
499 /**
500  * frescan_fna_vres_get_remaining_budget()
501  *
502  * This function stores in the variable pointed to by budget the
503  * remaining execution-time budget associated with the specified
504  * vres in the present period.
505  *
506  * @param[in] resource_id The network we are referring to (a protocol
507  * could be able to handle several networks at the same time)
508  * @param[in] vres The internal virtual resource id
509  * @param[out] remaining_budget  The remaining budget for this period
510  *
511  *  @return
512  *   0 if there are no errors \n
513  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
514  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
515  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
516  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
517  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
518  *
519  **/
520 int frescan_fna_vres_get_remaining_budget
521                 (const frsh_resource_id_t resource_id,
522                  const fna_vres_id_t vres,
523                  struct timespec *remaining_budget)
524 {
525         FRESCAN_ERROR("not implemented\n");
526         return -1;
527 }
528
529 /**
530  * frescan_fna_vres_get_budget_and_period()
531  *
532  * This function gets the budget and period associated with the specified vres
533  * for each period. If one of these pointers is NULL, the corresponding
534  * information is not stored.
535  *
536  * @param[in] resource_id The network we are referring to (a protocol
537  * could be able to handle several networks at the same time)
538  * @param[in] vres The internal virtual resource id
539  * @param[out] budget The budget associated to vres
540  * @param[out] period  The period associated to vres
541  *
542  * @return
543  *   0 if there are no errors \n
544  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
545  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
546  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
547  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
548  *   FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
549  *
550  **/
551 int frescan_fna_vres_get_budget_and_period
552                 (const frsh_resource_id_t resource_id,
553                  const fna_vres_id_t vres,
554                  struct timespec *budget,
555                  struct timespec *period)
556 {
557         int ret;
558         frescan_server_params_t server_params;
559
560         ret =  frescan_servers_get_data((frescan_network_t)resource_id,
561                                          &server_params,
562                                          (frescan_ss_t)vres);
563         if (ret != 0) return ret;
564
565         *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
566                                         server_params.budget);
567
568         *period = server_params.period;
569
570         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
571               "budget(%d packets %ld us\n",
572               server_params.budget, frsh_rel_time_to_usec(*budget));
573
574         return 0;
575 }
576
577 /*@}*/
578
579 ///////////////////////////////////////////////////////////////////
580 //           SPARE CAPACITY FUNCIONS
581 ///////////////////////////////////////////////////////////////////
582
583 /**
584  * @defgroup fnaspare FNA Spare Capacity
585  * @ingroup fna
586  *
587  * The following functions are used to get spare capacity data
588  *
589  * @{
590  **/
591
592 /**
593  * frescan_fna_resource_get_capacity()
594  *
595  * This operation gets the spare capacity currently assigned to a importance
596  * level. If we divide this value by UINT32_MAX we will get the network
597  * utilization associated to the spare capacity of a importance level.
598  *
599  * The following is typically in stdint.h: \n
600  *  - typedef unsigned int uint32_t;  \n
601  *  - # define UINT32_MAX  (4294967295U)  \n
602  *
603  * @param[in] resource_id The network we are referring to (a protocol
604  * could be able to handle several networks at the same time)
605  * @param[in] importance The importance we want the capacity of
606  * @param[out] capacity The spare capacity for that importance level
607  *
608  * @return
609  *   0 if there are no errors \n
610  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
611  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
612  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
613  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
614  *
615  **/
616 int frescan_fna_resource_get_capacity
617                 (const frsh_resource_id_t resource_id,
618                  const int importance,
619                  uint32_t *capacity)
620 {
621         FRESCAN_ERROR("not implemented\n");
622         return -1;
623 }
624
625 /**
626  * frescan_fna_resource_get_total_weight()
627  *
628  * This function gets the sum of the weight parameters for all vres in a
629  * network of an importance level.
630  *
631  * @param[in] resource_id The network we are referring to (a protocol
632  * could be able to handle several networks at the same time)
633  * @param[in] importance The importance we want the total weight of
634  * @param[out] total_weight The total weight for that importance level
635  *
636  * @return
637  *   0 if there are no errors \n
638  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
639  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
640  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
641  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
642  *
643  **/
644 int frescan_fna_resource_get_total_weight
645                 (const frsh_resource_id_t resource_id,
646                  const int importance,
647                  int *total_weight)
648 {
649         FRESCAN_ERROR("not implemented\n");
650         return -1;
651 }
652
653 /**
654  * frescan_fna_vres_decrease_capacity()
655  *
656  * This function allows to ask for less budget and period than what we
657  * received. The request must be compatible with the rest of contract
658  * parameters of the vres. If we want to recover the released capacity
659  * we will need to renegotiate.
660  *
661  * @param[in] resource_id The network we are referring to (a protocol
662  * could be able to handle several networks at the same time)
663  * @param[in] vres The internal virtual resource id
664  * @param[in] new_budget The new_budget
665  * @param[in] new_period The new Period
666  *
667  * @return
668  *   0 if there are no errors \n
669  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
670  *   FNA_ERR_NOT_CONTRACTED_VRES: if the vres is not contracted \n
671  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
672  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
673  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
674  *   FNA_ERR_CONTRACT_REJECTED: if it is incompatible with the current
675  *      contract \n
676  *
677  **/
678 int frescan_fna_vres_decrease_capacity
679                 (const frsh_resource_id_t resource_id,
680                  const fna_vres_id_t vres,
681                  const struct timespec new_budget,
682                  const struct timespec new_period)
683 {
684         FRESCAN_ERROR("not implemented\n");
685         return -1;
686 }
687
688 ///////////////////////////////////////////////////////////////////
689 //           SEND RECEIVE OPERATIONS
690 ///////////////////////////////////////////////////////////////////
691
692 /**
693  * frescan_fna_send_sync()
694  *
695  * Similar to previous function but now the sending thread gets blocked
696  * until the message is already sent to the network.
697  *
698  * @param[in] endpoint The send endpoint we are sending through. It must
699  *    be bound to a virtual resource (resource_id is in the endpoint).
700  * @param[in] msg The message we want to send
701  * @param[in] size The size in bytes of the message
702  *
703  * @returns
704  *   0 if there are no errors \n
705  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
706  *   FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
707  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
708  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
709  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
710  *   FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
711  *   FNA_ERR_BUFFER_FULL: if the message has been discarded because
712  *   the queue is full (and does not have the policy FNA_QP_OLDEST) \n
713  *
714  **/
715 int frescan_fna_send_sync
716                 (const fna_endpoint_data_t *endpoint,
717                  const void *msg,
718                  const size_t size)
719 {
720         FRESCAN_ERROR("not implemented\n");
721         return -1;
722 }
723
724 /**
725  * frescan_fna_send_async()
726  *
727  * This operation sends a message stored in msg and of length size
728  * through the given send endpoint. The operation is non-blocking and
729  * returns immediately.
730  *
731  * @param[in] endpoint The send endpoint we are sending through. It must
732  *    be bound to a virtual resource (resource_id is in the endpoint).
733  * @param[in] msg The message we want to send
734  * @param[in] size The size in bytes of the message
735  *
736  * @returns
737  *   0 if there are no errors \n
738  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
739  *   FNA_ERR_NOT_BOUND: if endpoint is not bound to a valid vres \n
740  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
741  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
742  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
743  *   FNA_ERR_TOO_LARGE: if the message is too large for the network protocol \n
744  *   FNA_ERR_BUFFER_FULL: if the message has been discarded because
745  *   the queue is full (and does not have the policy FNA_QP_OLDEST) \n
746  *
747  **/
748 int frescan_fna_send_async
749                 (const fna_endpoint_data_t *endpoint,
750                  const void *msg,
751                  const size_t size)
752 {
753         int ret;
754         frescan_send_params_t params;
755
756         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
757               "net:%u dest:%u chan:%u size:%u ss:%u\n",
758               endpoint->resource_id, endpoint->destination,
759               endpoint->stream_id, size, endpoint->vres);
760
761         params.net      = (frescan_network_t)endpoint->resource_id;
762         params.to       = (frescan_node_t)endpoint->destination;
763         params.channel  = (frescan_channel_t)endpoint->stream_id;
764         params.flags    = FRESCAN_SS | FRESCAN_ASYNC;
765         params.ss       = endpoint->vres;
766
767         ret = frescan_send(&params, (uint8_t *)msg, size);
768         if (ret != 0) {
769                 FRESCAN_ERROR ("could not send message\n");
770                 return -1;
771         }
772
773         return 0;
774 }
775
776 /**
777  * frescan_fna_receive_sync()
778  *
779  * This operation is used to receive messages from the network with a
780  * blocking behavior (if there are no messages this operation blocks
781  * the calling thread).
782  *
783  * When a message is available, it is copied to buffer (up to its size).
784  * The number of bytes copied is returned in received_bytes. The rest
785  * of the bytes of that message will be lost or not depending on the
786  * protocol (FNA_ERR_NO_SPACE will be returned if it is).
787  *
788  * The function fails with FNA_ERR_NO_SPACE if the buffersize is
789  * too small for the message received.  In this case the message is
790  * lost.
791  *
792  * Messages arriving at a receiver buffer that is full will be handled
793  * according to the queueing policy of the endpoint (overwrite oldest,
794  * discard it,etc).
795  *
796  * @param[in] endpoint The receive endpoint we are receiving from.
797  *    (resource_id is in the endpoint).
798  * @param[out] buffer Buffer for storing the received message
799  * @param[in] buffer_size The size in bytes of this buffer
800  * @param[out] received_bytes The actual number of received bytes
801  * @param[out] from Address of the sender node
802  *
803  * @return
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
809  *   FNA_ERR_NO_SPACE: if the message size is bigger than the
810  *      provided buffer. \n
811  *
812  **/
813 int frescan_fna_receive_sync
814                 (const fna_endpoint_data_t *endpoint,
815                  void *buffer,
816                  const size_t buffer_size,
817                  size_t *received_bytes,
818                  frsh_network_address_t *from)
819 {
820         int ret;
821         frescan_recv_params_t params;
822         frescan_node_t frescan_from;
823         frescan_prio_t prio;
824
825         params.net      = (frescan_network_t)endpoint->resource_id;
826         params.channel  = (frescan_channel_t)endpoint->stream_id;
827         params.flags    = FRESCAN_SYNC;
828
829         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
830               "net:%u chan:%u size:%u\n",
831               endpoint->resource_id, endpoint->stream_id, buffer_size);
832
833         ret = frescan_recv(&params, (uint8_t *)buffer, buffer_size,
834                            received_bytes, &frescan_from, &prio);
835
836         if (ret != 0) {
837                 FRESCAN_ERROR ("error while receiving message");
838                 return -1;
839         }
840
841         *from = (frsh_network_address_t)frescan_from;
842
843         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
844               "msg received, from:%u bytes:%u prio:%u\n",
845               *from, *received_bytes, prio);
846
847         return 0;
848 }
849
850 /**
851  * frescan_fna_receive_async()
852  *
853  * This operation is similar to the previous one but it works in a non
854  * blocking (asynchronous) fashion.  If no message is available it
855  * returns with error FNA_NO_MESSAGE.
856  *
857  * @param[in] endpoint The receive endpoint we are receiving from.
858  *    (resource_id is in the endpoint).
859  * @param[out] buffer Buffer for storing the received message
860  * @param[in] buffer_size The size in bytes of this buffer
861  * @param[out] received_bytes The actual number of received bytes
862  * @param[out] from Address of the sender node
863  *
864  * @return
865  *   0 if there are no errors \n
866  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
867  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
868  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
869  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
870  *   FNA_ERR_NO_SPACE: if the message size is bigger than the
871  *      provided buffer. \n
872  *   FNA_NO_MESSAGE: if no messages are available in the queue. \n
873  *
874  **/
875 int frescan_fna_receive_async
876                 (const fna_endpoint_data_t *endpoint,
877                  void *buffer,
878                  const size_t buffer_size,
879                  size_t *received_bytes,
880                  frsh_network_address_t *from)
881 {
882         FRESCAN_ERROR("not implemented\n");
883         return -1;
884 }
885
886 /**
887  * frescan_fna_send_endpoint_get_status()
888  *
889  * This function tells the number of messages still pending in the
890  * endpoint queue, whether the network is up or down with some
891  * optional information which is protocol_dependent.
892  *
893  * @param[in] endpoint The send endpoint (resource_id is in the endpoint).
894  * @param[out] number_of_pending_messages The number of pending messages
895  * @param[out] network_status How is the network (up, down..)
896  * @param[out] protocol_status Protocol dependent status info
897  *
898  * @return
899  *   0 if there are no errors \n
900  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
901  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
902  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
903  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
904  *
905  **/
906 int frescan_fna_send_endpoint_get_status
907                 (const fna_endpoint_data_t *endpoint,
908                  int *number_of_pending_messages,
909                  frsh_endpoint_network_status_t *network_status,
910                  frsh_protocol_status_t *protocol_status)
911 {
912         FRESCAN_ERROR("not implemented\n");
913         return -1;
914 }
915
916 /**
917  * frescan_fna_receive_endpoint_created()
918  *
919  * This operation is a called from frsh_receive_endpoint_create with a
920  * receive_endpoint structure already filled.
921  *
922  * Receiving endpoints are not bound to any network vres, this is
923  * because don't originate any traffic.
924  *
925  * @param[in] endpoint the endpoint object.
926  *
927  * @return
928  *   0 if there are no errors \n
929  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
930  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
931  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
932  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
933  **/
934 int frescan_fna_receive_endpoint_created
935                 (fna_endpoint_data_t *endpoint)
936 {
937         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
938         return 0;
939 }
940
941 /**
942  * frescan_fna_receive_endpoint_get_pending_messages
943  *
944  * This function tells the number of messages still pending in the
945  * endpoint queue, whether the network is up or down and some optional
946  * information which is protocol dependent.
947  *
948  * @param[in] endpoint The receive endpoint (resource_id is in the endpoint).
949  * @param[out] number_of_pending_messages The number of pending messages
950  * @param[out] network_status How is the network (up, down..)
951  * @param[out] protocol_status Protocol dependent status info
952  *
953  * @return
954  *   0 if there are no errors \n
955  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
956  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
957  *   FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
958  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
959  *
960  **/
961 int frescan_fna_receive_endpoint_get_status
962                 (const fna_endpoint_data_t *endpoint,
963                  int *number_of_pending_messages,
964                  frsh_endpoint_network_status_t *network_status,
965                  frsh_protocol_status_t *protocol_status)
966 {
967         FRESCAN_ERROR("not implemented\n");
968         return -1;
969 }
970
971 //////////////////////////////////////////////////////////////////////
972 //           NETWORK CONFIGURATION FUNCTIONS
973 //////////////////////////////////////////////////////////////////////
974
975 /**
976  * frescan_fna_network_get_max_message_size()
977  *
978  * This operation gives the maximum number of bytes that can be sent
979  * at a time through the send function when using the network designated by
980  * 'resource_id' and sending it to 'destination'.
981  *
982  * If the application needs to send bigger messages it will have to
983  * split them.
984  *
985  * Some protocols, like IP, are capable of sending large messages
986  * (and use fragmentation internally) but other protocols don't.
987  *
988  * @param[in] resource_id The network we want the tx time from.
989  * @param[in] destination The destination address
990  * @param[out] max_size The maximum number of bytes for each message
991  *
992  * @return
993  *   0 if there are no errors \n
994  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
995  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
996  *   FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
997  *   a network accessible from the current processing node \n
998  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
999  *   invalid \n
1000  *
1001  **/
1002 int frescan_fna_network_get_max_message_size
1003                 (const frsh_resource_id_t resource_id,
1004                  const frsh_network_address_t destination,
1005                  size_t *max_size)
1006 {
1007         FRESCAN_ERROR("not implemented\n");
1008         return -1;
1009 }
1010
1011 /**
1012  * frescan_fna_network_bytes_to_budget()
1013  *
1014  * This operation converts a number of bytes into a temporal budget for
1015  * a specific network. Network overheads are not included here but are
1016  * considered internally when negotiating a specific contract.
1017  *
1018  * @param[in] resource_id The network
1019  * @param[in] nbytes Number of bytes
1020  * @param[out] budget The network budget for nbytes
1021  *
1022  * @return
1023  *   0 if there are no errors \n
1024  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1025  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1026  *   FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1027  *   a network accessible from the current processing node \n
1028  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
1029  *   than zero \n
1030  *
1031  **/
1032 int frescan_fna_network_bytes_to_budget
1033                 (const frsh_resource_id_t resource_id,
1034                  const size_t nbytes,
1035                  frsh_rel_time_t *budget)
1036 {
1037         int number_of_packets;
1038
1039         if (budget == NULL || nbytes < 0) {
1040                 return -1;
1041         }
1042
1043         // number of FRESCAN frames (8 bytes)
1044         number_of_packets = (int) ceil((double)nbytes / 8.0);
1045         *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
1046                                               number_of_packets);
1047
1048         DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
1049               "bytes: %d -> budget: %ld us\n",
1050                nbytes, frsh_rel_time_to_usec(*budget));
1051
1052         return 0;
1053 }
1054
1055 /**
1056  * frescan_fna_network_budget_to_bytes()
1057  *
1058  * This operation converts a temporal budget into a number of bytes for
1059  * a specific network. Network overheads are not included.
1060  *
1061  * @param[in] resource_id The network
1062  * @param[in] budget The network budget for nbytes
1063  * @param[out] nbytes Number of bytes
1064  *
1065  * @return
1066  *   0 if there are no errors \n
1067  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1068  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1069  *   FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1070  *   a network accessible from the current processing node \n
1071  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
1072  *   an invalid time value \n
1073  *
1074  **/
1075 int frescan_fna_network_budget_to_bytes
1076                 (const frsh_resource_id_t resource_id,
1077                  const frsh_rel_time_t *budget,
1078                  size_t *nbytes)
1079 {
1080         int number_of_packets;
1081
1082         if (budget == NULL || nbytes == NULL) {
1083                 return -1;
1084         }
1085
1086         number_of_packets = frsh_rel_time_to_usec(*budget) /
1087                             FRESCAN_FRAME_TX_TIME_US;
1088
1089         *nbytes = number_of_packets * 8;
1090
1091         return 0;
1092 }
1093
1094 /**
1095  * frescan_fna_network_get_min_eff_budget()
1096  *
1097  * This operation gets the minimum effective budget for a network. Each message
1098  * consumes a contracted budget in "chunks" (i.e: packets) that we call
1099  * minimum effective budget.
1100  *
1101  * A negotiated contract, for N bytes in a period T, means that there is a
1102  * virtual resource that reserves for the user:
1103  *
1104  *   Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
1105  *
1106  * Note that if the user decides not to send these N bytes at once but, say,
1107  * one byte at a time, it will consume one "CHUNK" at a time and the reserved
1108  * budget will become exhausted before sending all the bytes.
1109  *
1110  * @param[in] resource_id The network
1111  * @param[out] budget The network budget
1112  *
1113  * @return
1114  *   0 if there are no errors \n
1115  *   FNA_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
1116  *   FNA_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
1117  *   FNA_ERR_RESOURCE_ID_INVALID: if resource id does not represent
1118  *   a network accessible from the current processing node \n
1119  *   FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
1120  *
1121  **/
1122 int frescan_fna_network_get_min_eff_budget
1123                 (const frsh_resource_id_t resource_id,
1124                  struct timespec *budget)
1125 {
1126         if (budget == NULL) {
1127                 return -1;
1128         }
1129
1130         *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
1131
1132         return 0;
1133 }
1134
1135 // GLOBAL variable to install the network protocol in FRESCOR
1136
1137 fna_operations_t frescan_fna_operations = {
1138 #ifdef CONFIG_FNA_FRESCAN_CONNECTED
1139         .fna_init = frescan_fna_init,
1140         .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
1141         .fna_contract_negotiate = frescan_fna_contract_negotiate,
1142         .fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
1143         .fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
1144         .fna_vres_get_renegotiation_status = frescan_fna_vres_get_renegotiation_status,
1145         .fna_vres_destroy = frescan_fna_vres_destroy,
1146         .fna_vres_get_contract = frescan_fna_vres_get_contract,
1147         .fna_vres_get_usage = frescan_fna_vres_get_usage,
1148         .fna_vres_get_remaining_budget = frescan_fna_vres_get_remaining_budget,
1149         .fna_vres_get_budget_and_period = frescan_fna_vres_get_budget_and_period,
1150         .fna_resource_get_capacity = frescan_fna_resource_get_capacity,
1151         .fna_resource_get_total_weight = frescan_fna_resource_get_total_weight,
1152         .fna_vres_decrease_capacity = frescan_fna_vres_decrease_capacity,
1153         .fna_send_sync = frescan_fna_send_sync,
1154         .fna_send_async = frescan_fna_send_async,
1155         .fna_receive_sync = frescan_fna_receive_sync,
1156         .fna_receive_async = frescan_fna_receive_async,
1157         .fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
1158         .fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
1159         .fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
1160 #endif
1161         .fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
1162         .fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
1163         .fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,
1164         .fna_network_get_min_eff_budget = frescan_fna_network_get_min_eff_budget
1165 };