//
// FNA(Frescor Network Adaptation layer), pronounced "efe ene a"
//==============================================================
+#include <malloc.h> // for malloc and free
-#ifndef _RTEP_FNA_H_
-#define _RTEP_FNA_H_
-
-#include "fna.h"
#include "rtep.h" // for rtep_adainit, rtep_valid_multicast_id, ..
#include "rtep_bandwith_reservation.h" // for rtep_bwres_*
-#include <malloc.h> // for malloc and free
+#include "rtep_fna.h" // function prototypes
+
+#include "frsh_freelist.h"
+
+#if 1
+#include <stdio.h>
+#define DEBUG(x,args...) printf("%s: " x, __func__ , ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+// TODO: add a mutex for concurrent access if necessary
+static rtep_bwres_vres_t rtep_vres_list[MAX_N_RTEP_BWRES_VRES];
+static frsh_freelist_t rtep_vres_freelist;
//////////////////////////////////////////////////////////////////////
// INITIALIZATION
//////////////////////////////////////////////////////////////////////
/**
- * fna_init()
+ * rtep_fna_init()
*
* This function will be hooked to the frsh_init function and it is
* intented to initialize the protocol and its structures.
* if the function has already been called before (with success) \n
*
**/
-int fna_init(const frsh_resource_id_t resource_id)
+int rtep_fna_init(const frsh_resource_id_t resource_id)
{
- rtep_adainit(); // init Ada bindings
- return rtep_bwres_init();
+ int err = 0;
+
+ DEBUG("starting rtep\n");
+
+ // init Ada bindings
+ rtep_adainit();
+
+ // initialize the freelist to handle the rtep_vres
+ err = frsh_freelist_init(&rtep_vres_freelist, MAX_N_RTEP_BWRES_VRES);
+ if (err != 0) return -1;
+
+ return rtep_bwres_init();
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/**
- * fna_contract_negotiate()
+ * rtep_fna_contract_negotiate()
*
* The operation negotiates a contract and if accepted it will return
* a fna_vres_id_t. It will also check that the given contract_id is unique
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_contract_negotiate
+int rtep_fna_contract_negotiate
(const frsh_resource_id_t resource_id,
const frsh_contract_t *contract,
fna_vres_id_t *vres)
{
- rtep_bwres_contract_t rtep_contract;
- rtep_bwres_vres_t *rtep_vres;
- int accepted;
-
- // convert FRSH contract to RTEP BWRES contract
- rtep_contract.period_max = contract->period_max;
- rtep_contract.deadline = contract->deadline;
- rtep_contract.prio = contract->preemption_level;
- // in RTEP BWRES, budget is given in number of packets. We do a little trick
- // in the function bytes_to_network_budget to use a the field tv_sec from the
- // timespec in frsh_contract to store the budget in bytes directly
- rtep_contract.budget_min = contract->budget_min.tv_sec;
-
- // create an internal vres. The fna vres id is a pointer to void which
- // we transform internally to a pointer to a vres structure
- rtep_vres = (rtep_bwres_vres_t *)malloc(sizeof(rtep_bwres_vres_t));
-
- // negotiate the contract
- accepted = rtep_bwres_contract_negotiate (&rtep_contract, rtep_vres);
-
- // vres is a pointer to void *, so we change void * for the new *rtep_vres
- if (accepted == 0){
- *vres = (void *)rtep_vres;
- }else{
- free(rtep_vres);
- }
+ rtep_bwres_contract_t rtep_contract;
+ int accepted;
+ int pos;
- return accepted;
+ // convert FRSH contract to RTEP BWRES contract
+ rtep_contract.period_max = contract->period_max;
+ rtep_contract.deadline = contract->deadline;
+ rtep_contract.prio = contract->preemption_level;
+ // in RTEP BWRES, budget is given in number of packets. We do a little trick
+ // in the function bytes_to_network_budget to use a the field tv_sec from
+ // the timespec in frsh_contract to store the budget in bytes directly
+ rtep_contract.budget_min = contract->budget_min.tv_sec;
+
+ // allocate a free internal vres.
+ pos = frsh_freelist_alloc(&rtep_vres_freelist);
+
+ if (pos < 0) {
+ return -1;
+ }
+
+ DEBUG("calling rtep_bwres_contract_negotiate\n");
+ // negotiate the contract
+ accepted = rtep_bwres_contract_negotiate
+ (&rtep_contract, &rtep_vres_list[pos]);
+
+ // if accepted assign the vres, if not deallocate the rtep_vres
+ if (accepted == 0) {
+ *vres = (fna_vres_id_t)pos;
+ } else {
+ frsh_freelist_free(&rtep_vres_freelist, pos);
+ }
+
+ return accepted;
}
/**
- * fna_contract_renegotiate_sync()
+ * rtep_fna_contract_renegotiate_sync()
*
* The operation renegotiates a contract for an existing vres. If
* the on-line admission test is enabled it determines whether the
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_contract_renegotiate_sync
+int rtep_fna_contract_renegotiate_sync
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
const frsh_contract_t *new_contract)
}
/**
- * fna_contract_renegotiate_async()
+ * rtep_fna_contract_renegotiate_async()
*
* The operation enqueues a renegotiate operation for an existing
* vres, and returns immediately. The renegotiate operation is
* NULL nor a valid POSIX signal \n
*
**/
-int fna_contract_renegotiate_async
+int rtep_fna_contract_renegotiate_async
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
const frsh_contract_t *new_contract,
}
/**
- * fna_vres_get_renegotiation_status()
+ * rtep_fna_vres_get_renegotiation_status()
*
* The operation reports on the status of the last renegotiation
* operation enqueued for the specified vres. It is callable even
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_vres_get_renegotiation_status
+int rtep_fna_vres_get_renegotiation_status
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
frsh_renegotiation_status_t *renegotiation_status)
}
/**
- * fna_vres_destroy()
+ * rtep_fna_vres_destroy()
*
* The operation eliminates the specified vres
* and recalculates all necessary parameters for the contracts
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_vres_destroy
+int rtep_fna_vres_destroy
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres)
{
- return 0;
+ int err = 0;
+ int pos = (int) vres;
+
+ // cancel de negotiated contract (the function spread results among nodes)
+ err = rtep_bwres_vres_destroy (&rtep_vres_list[pos]);
+ if (err != 0) return -1;
+
+ // free the element in the rtep_vres list
+ err = frsh_freelist_free(&rtep_vres_freelist, pos);
+ if (err != 0) return -1;
+
+ return 0;
}
/**
- * fna_vres_get_contract()
+ * rtep_fna_vres_get_contract()
*
* This operation stores the contract parameters currently associated
* with the specified vres in the variable pointed to by
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_vres_get_contract
+int rtep_fna_vres_get_contract
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
frsh_contract_t *contract)
}
/**
- * fna_vres_get_usage()
+ * rtep_fna_vres_get_usage()
*
* This function gets the execution time spent by all messages that have been
* sent through the specified vres.
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_vres_get_usage
+int rtep_fna_vres_get_usage
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
struct timespec *usage)
}
/**
- * fna_vres_get_remaining_budget()
+ * rtep_fna_vres_get_remaining_budget()
*
* This function stores in the variable pointed to by budget the
* remaining execution-time budget associated with the specified
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_vres_get_remaining_budget
+int rtep_fna_vres_get_remaining_budget
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
struct timespec *remaining_budget)
}
/**
- * fna_vres_get_budget_and_period()
+ * rtep_fna_vres_get_budget_and_period()
*
* This function gets the budget and period associated with the specified vres
* for each period. If one of these pointers is NULL, the corresponding
* FNA_ERR_BAD_ARGUMENT: if both pointers are NULL \n
*
**/
-int fna_vres_get_budget_and_period
+int rtep_fna_vres_get_budget_and_period
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
struct timespec *budget,
**/
/**
- * fna_resource_get_capacity()
+ * rtep_fna_resource_get_capacity()
*
* This operation gets the spare capacity currently assigned to a importance
* level. If we divide this value by UINT32_MAX we will get the network
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_resource_get_capacity
+int rtep_fna_resource_get_capacity
(const frsh_resource_id_t resource_id,
const int importance,
uint32_t *capacity)
}
/**
- * fna_resource_get_total_weight()
+ * rtep_fna_resource_get_total_weight()
*
* This function gets the sum of the weight parameters for all vres in a
* network of an importance level.
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_resource_get_total_weight
+int rtep_fna_resource_get_total_weight
(const frsh_resource_id_t resource_id,
const int importance,
int *total_weight)
}
/**
- * fna_vres_decrease_capacity()
+ * rtep_fna_vres_decrease_capacity()
*
* This function allows to ask for less budget and period than what we
* received. The request must be compatible with the rest of contract
* contract \n
*
**/
-int fna_vres_decrease_capacity
+int rtep_fna_vres_decrease_capacity
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres,
const struct timespec new_budget,
///////////////////////////////////////////////////////////////////
/**
- * fna_send_sync()
+ * rtep_fna_send_sync()
*
* Similar to previous function but now the sending thread gets blocked
* until the message is already sent to the network.
* the queue is full (and does not have the policy FNA_QP_OLDEST) \n
*
**/
-int fna_send_sync
- (const fna_send_endpoint_t *endpoint,
+int rtep_fna_send_sync
+ (const fna_endpoint_data_t *endpoint,
const void *msg,
const size_t size)
{
}
/**
- * fna_send_async()
+ * rtep_fna_send_async()
*
* This operation sends a message stored in msg and of length size
* through the given send endpoint. The operation is non-blocking and
* the queue is full (and does not have the policy FNA_QP_OLDEST) \n
*
**/
-int fna_send_async
- (const fna_send_endpoint_t *endpoint,
+int rtep_fna_send_async
+ (const fna_endpoint_data_t *endpoint,
const void *msg,
const size_t size)
{
- return 0;
+ DEBUG("dest: %d, chan: %d, size: %d, server: %d\n",
+ endpoint->destination, endpoint->stream_id, size,
+ rtep_vres_list[endpoint->vres].server_id);
+
+ // TODO: check errors
+ rtep_server_send_info
+ ((rtep_station_id_t) endpoint->destination,
+ (rtep_channel_t) endpoint->stream_id,
+ (uint8_t *) msg,
+ size,
+ rtep_vres_list[endpoint->vres].server_id,
+ 0); // not blocking
+ return 0;
}
/**
- * fna_receive_sync()
+ * rtep_fna_receive_sync()
*
* This operation is used to receive messages from the network with a
* blocking behavior (if there are no messages this operation blocks
* provided buffer. \n
*
**/
-int fna_receive_sync
- (const frsh_receive_endpoint_t *endpoint,
+int rtep_fna_receive_sync
+ (const fna_endpoint_data_t *endpoint,
void *buffer,
const size_t buffer_size,
size_t *received_bytes,
frsh_network_address_t *from)
{
- return 0;
+ rtep_priority_t prio;
+ rtep_station_id_t rtep_from;
+
+ // TODO: checks for errors
+ rtep_recv_info
+ (&rtep_from,
+ (rtep_channel_t) endpoint->stream_id,
+ (uint8_t *) buffer,
+ buffer_size,
+ received_bytes,
+ &prio);
+
+ *from = rtep_from;
+
+ DEBUG(" %u bytes, from %u, prio %u\n", *received_bytes, rtep_from, prio);
+
+ return 0;
}
/**
- * fna_receive_async()
+ * rtep_fna_receive_async()
*
* This operation is similar to the previous one but it works in a non
* blocking (asynchronous) fashion. If no message is available it
* FNA_NO_MESSAGE: if no messages are available in the queue. \n
*
**/
-int fna_receive_async
- (const frsh_receive_endpoint_t *endpoint,
+int rtep_fna_receive_async
+ (const fna_endpoint_data_t *endpoint,
void *buffer,
const size_t buffer_size,
size_t *received_bytes,
}
/**
- * fna_send_endpoint_get_status()
+ * rtep_fna_send_endpoint_get_status()
*
* This function tells the number of messages still pending in the
* endpoint queue, whether the network is up or down with some
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_send_endpoint_get_status
- (const fna_send_endpoint_t *endpoint,
+int rtep_fna_send_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
int *number_of_pending_messages,
- frsh_endpoint_network_status *network_status,
+ frsh_endpoint_network_status_t *network_status,
frsh_protocol_status_t *protocol_status)
{
return 0;
}
/**
- * fna_receive_endpoint_create_callback()
+ * rtep_fna_receive_endpoint_created()
*
* This operation is a called from frsh_receive_endpoint_create with a
* receive_endpoint structure already filled.
* FNA_ERR_RESOURCE_ID_INVALID: if we are not in charge of resource_id \n
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
**/
-int fna_receive_endpoint_create_callback
- (const frsh_receive_endpoint_t *endpoint)
+int rtep_fna_receive_endpoint_created
+ (const fna_endpoint_data_t *endpoint)
{
return 0;
}
/**
- * fna_receive_endpoint_get_pending_messages
+ * rtep_fna_receive_endpoint_get_pending_messages
*
* This function tells the number of messages still pending in the
* endpoint queue, whether the network is up or down and some optional
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_receive_endpoint_get_status
- (const frsh_receive_endpoint_t *endpoint,
+int rtep_fna_receive_endpoint_get_status
+ (const fna_endpoint_data_t *endpoint,
int *number_of_pending_messages,
- frsh_endpoint_network_status *network_status,
+ frsh_endpoint_network_status_t *network_status,
frsh_protocol_status_t *protocol_status)
{
return 0;
//////////////////////////////////////////////////////////////////////
/**
- * fna_network_get_max_message_size()
+ * rtep_fna_network_get_max_message_size()
*
* This operation gives the maximum number of bytes that can be sent
* at a time through the send function when using the network designated by
* invalid \n
*
**/
-int fna_network_get_max_message_size
+int rtep_fna_network_get_max_message_size
(const frsh_resource_id_t resource_id,
const frsh_network_address_t destination,
size_t *max_size)
{
- int is_multicast;
+ int is_multicast;
- if (max_size == NULL) {
- return -1;
- }
+ if (max_size == NULL) {
+ return -1;
+ }
- is_multicast = rtep_valid_multicast_id ((rtep_station_id_t) destination);
- if (is_multicast) {
- *max_size = MULTICAST_MTU;
- } else {
- *max_size = MAX_RTEP_MTU;
- }
- return 0;
+ is_multicast = rtep_valid_multicast_id ((rtep_station_id_t) destination);
+ if (is_multicast) {
+ *max_size = MULTICAST_MTU;
+ } else {
+ *max_size = MAX_RTEP_MTU;
+ }
+ return 0;
}
/**
- * fna_network_bytes_to_budget()
+ * rtep_fna_network_bytes_to_budget()
*
* This operation converts a number of bytes into a temporal budget for
* a specific network. Network overheads are not included here but are
* than zero \n
*
**/
-int fna_network_bytes_to_budget
+int rtep_fna_network_bytes_to_budget
(const frsh_resource_id_t resource_id,
const size_t nbytes,
struct timespec *budget)
{
- int number_of_packets;
+ int number_of_packets;
- if (budget == NULL || nbytes < 0) {
- return -1;
- }
+ if (budget == NULL || nbytes < 0) {
+ return -1;
+ }
// we measure the budget in number of RTEP packets of maximum size
- number_of_packets = nbytes / MAX_RTEP_MTU + 1;
+ number_of_packets = nbytes / MAX_RTEP_MTU + 1;
// we store the budget in number of packets instead of in time. We
// use a field in the timespec structure.
- budget->tv_sec = number_of_packets;
-
- return 0;
+ budget->tv_sec = number_of_packets;
+ DEBUG("bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
+ return 0;
}
/**
- * fna_network_budget_to_bytes()
+ * rtep_fna_network_budget_to_bytes()
*
* This operation converts a temporal budget into a number of bytes for
* a specific network. Network overheads are not included.
* an invalid time value \n
*
**/
-int fna_network_budget_to_bytes
+int rtep_fna_network_budget_to_bytes
(const frsh_resource_id_t resource_id,
const struct timespec *budget,
size_t *nbytes)
{
- int number_of_packets;
+ int number_of_packets;
- if (budget == NULL || nbytes == NULL) {
- return -1;
- }
- number_of_packets = budget->tv_sec;
- *nbytes = number_of_packets * MAX_RTEP_MTU;
- return 0;
+ if (budget == NULL || nbytes == NULL) {
+ return -1;
+ }
+ number_of_packets = budget->tv_sec;
+ *nbytes = number_of_packets * MAX_RTEP_MTU;
+ return 0;
}
/**
- * fna_network_get_min_effective_budget()
+ * rtep_fna_network_get_min_eff_budget()
*
* This operation gets the minimum effective budget for a network. Each message
* consumes a contracted budget in "chunks" (i.e: packets) that we call
* FNA_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
**/
-int fna_network_get_min_effective_budget
+int rtep_fna_network_get_min_eff_budget
(const frsh_resource_id_t resource_id,
struct timespec *budget)
{
return 0;
}
-#endif // _RTEP_FNA_H_
+// GLOBAL variable to install the network protocol in FRESCOR
+
+fna_operations_t rtep_fna_operations = {
+ .fna_init = rtep_fna_init,
+ .fna_contract_negotiate = rtep_fna_contract_negotiate,
+ .fna_contract_renegotiate_sync = rtep_fna_contract_renegotiate_sync,
+ .fna_contract_renegotiate_async = rtep_fna_contract_renegotiate_async,
+ .fna_vres_get_renegotiation_status = rtep_fna_vres_get_renegotiation_status,
+ .fna_vres_destroy = rtep_fna_vres_destroy,
+ .fna_vres_get_contract = rtep_fna_vres_get_contract,
+ .fna_vres_get_usage = rtep_fna_vres_get_usage,
+ .fna_vres_get_remaining_budget = rtep_fna_vres_get_remaining_budget,
+ .fna_vres_get_budget_and_period = rtep_fna_vres_get_budget_and_period,
+ .fna_resource_get_capacity = rtep_fna_resource_get_capacity,
+ .fna_resource_get_total_weight = rtep_fna_resource_get_total_weight,
+ .fna_vres_decrease_capacity = rtep_fna_vres_decrease_capacity,
+ .fna_send_sync = rtep_fna_send_sync,
+ .fna_send_async = rtep_fna_send_async,
+ .fna_receive_sync = rtep_fna_receive_sync,
+ .fna_receive_async = rtep_fna_receive_async,
+ .fna_send_endpoint_get_status = rtep_fna_send_endpoint_get_status,
+ .fna_receive_endpoint_created = rtep_fna_receive_endpoint_created,
+ .fna_receive_endpoint_get_status = rtep_fna_receive_endpoint_get_status,
+ .fna_network_get_max_message_size = rtep_fna_network_get_max_message_size,
+ .fna_network_bytes_to_budget = rtep_fna_network_bytes_to_budget,
+ .fna_network_budget_to_bytes = rtep_fna_network_budget_to_bytes,
+ .fna_network_get_min_eff_budget = rtep_fna_network_get_min_eff_budget
+};
+
+// TODO: move this out of here
+
+#include "fna_configuration.h"
+fna_operations_t *fna_operations[FNA_MAX_NETWORKS] = {
+ &rtep_fna_operations, // resource_id 0 (default) --> RTEP
+ NULL, // resource_id 1
+ NULL, // resource_id 2
+ NULL // resource_id 3
+};
+/*
+ * test_c_rtep_frsh_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP functions defined at frsh_fna.h
+ * which is the public part of frsh_fna.h. The interface of this public part
+ * is dependent of the underlying network protocol. We are not trying here to
+ * make a very intense test but a simple and basic one to check the correct
+ * behaviour of the functions.
+ *
+ * Algorithm:
+ *
+ * First we check the conversions between frsh and rtep addresses and streams.
+ * Then, we check the renegotiation functions for the period of the internal
+ * negotiation messages. And finally, we check the renegotiation functions for
+ * the internal service thread.
+ *
+ */
+
#include <assert.h> // for assert
#include <stdio.h> // for printf
+#include <stdbool.h> // for bool
#include "frsh_core_types.h" // for FRSH_RESOURCE_ID_DEFAULT
-#include "frsh_distributed_types.h" // for frsh_network_address_t, frsh_stream_id_t
-#include "fna.h" // for fna_init
-#include "frsh_fna.h" // for frsh_rtep_*
+#include "frsh_distributed_types.h" // frsh_network_address_t, frsh_stream_id_t
+
+#include "rtep_fna.h" // for rtep_fna_operations.fna_init
#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+#include "frsh_fna.h" // for frsh_rtep_*
+
int main ()
{
- int err;
- rtep_station_id_t rtep_station = 3;
- frsh_network_address_t frsh_address;
- rtep_channel_t in_stream = 7;
- frsh_stream_id_t out_stream;
- struct timespec neg_period = {2,0};
- struct timespec get_period = {0,0};
-
- printf("1.- fna_init\n");
- printf("--------------------------------------------------\n");
- err=fna_init(FRSH_RESOURCE_ID_DEFAULT);
- assert(err == 0);
-
- printf("2.- frsh_rtep_map_network_address\n");
- printf("--------------------------------------------------\n");
- err=frsh_rtep_map_network_address
- (FRSH_RESOURCE_ID_DEFAULT, rtep_station, &frsh_address);
- assert(err == 0);
- printf("rtep_address: %d, frsh_address: %d\n", rtep_station, frsh_address);
- assert(rtep_station == frsh_address);
-
- printf("3.- frsh_rtep_map_stream_id\n");
- printf("--------------------------------------------------\n");
- err=frsh_rtep_map_stream_id
- (FRSH_RESOURCE_ID_DEFAULT, in_stream, &out_stream);
- assert(err == 0);
- printf("rtep_channel: %d, frsh_stream: %d\n", in_stream, out_stream);
- assert(in_stream == out_stream);
-
- printf("4.- frsh_rtep_negotiation_messages_vres_renegotiate period\n");
- printf("--------------------------------------------------\n");
- err=frsh_rtep_negotiation_messages_vres_get_period
- (FRSH_RESOURCE_ID_DEFAULT, &get_period);
- assert(err == 0);
- printf("get_period sec=%d nsec=%d\n", get_period.tv_sec, get_period.tv_nsec);
-
- err=frsh_rtep_negotiation_messages_vres_renegotiate
- (FRSH_RESOURCE_ID_DEFAULT, &neg_period);
- printf("renegotiation accepted: %d\n", !err);
- assert(err == 0);
-
- err=frsh_rtep_negotiation_messages_vres_get_period
- (FRSH_RESOURCE_ID_DEFAULT, &get_period);
- assert(err == 0);
- printf("get_period sec=%d nsec=%d\n", get_period.tv_sec, get_period.tv_nsec);
-
- return 0;
+ int err;
+ rtep_station_id_t rtep_station = 3;
+ frsh_network_address_t frsh_address;
+ rtep_channel_t in_stream = 7;
+ frsh_stream_id_t out_stream;
+ struct timespec neg_period = {2,0};
+ struct timespec get_period = {0,0};
+ struct timespec rtep_serv_thread_budget = {1,0};
+ struct timespec rtep_serv_thread_period = {5,0};
+ bool serv_thread_renegotiation_accepted = false;
+ struct timespec current_serv_thread_budget = {0,0};
+ struct timespec current_serv_thread_period = {0,0};
+
+ printf("1.- fna_init\n");
+ err=rtep_fna_operations.fna_init(FRSH_RESOURCE_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("2.- frsh_rtep_map_network_address\n");
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, rtep_station, &frsh_address);
+ assert(err == 0);
+ printf("rtep_address:%d -> frsh_address:%d\n", rtep_station, frsh_address);
+ assert(rtep_station == frsh_address);
+
+ printf("3.- frsh_rtep_map_stream_id\n");
+ err=frsh_rtep_map_stream_id
+ (FRSH_RESOURCE_ID_DEFAULT, in_stream, &out_stream);
+ assert(err == 0);
+ printf("rtep_channel:%d -> frsh_stream:%d\n", in_stream, out_stream);
+ assert(in_stream == out_stream);
+
+ printf("4.- frsh_rtep_negotiation_messages_vres_renegotiate period\n");
+ err=frsh_rtep_negotiation_messages_vres_get_period
+ (FRSH_RESOURCE_ID_DEFAULT, &get_period);
+ assert(err == 0);
+ printf("period before renegotiation: sec=%d nsec=%d\n",
+ get_period.tv_sec, get_period.tv_nsec);
+
+ err=frsh_rtep_negotiation_messages_vres_renegotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &neg_period);
+ if (err == 0) {
+ printf("renegotiation accepted (period negotiated: sec=%d nsec=%d)\n",
+ neg_period.tv_sec, neg_period.tv_nsec);
+ } else {
+ printf("renegotiation not accepted\n");
+ }
+ assert (err == 0);
+
+ err=frsh_rtep_negotiation_messages_vres_get_period
+ (FRSH_RESOURCE_ID_DEFAULT, &get_period);
+ assert(err == 0);
+ printf("period after renegotiation: sec=%d nsec=%d\n",
+ get_period.tv_sec, get_period.tv_nsec);
+
+// TODO: uncomment step 5 when internal thread has a frescor contract
+// printf("5.- frsh_rtep_service_thread_vres_renegotiate\n");
+//
+// err=frsh_rtep_service_thread_vres_get_budget_and_period
+// (FRSH_RESOURCE_ID_DEFAULT,
+// ¤t_serv_thread_budget,
+// ¤t_serv_thread_period);
+// assert(err == 0);
+// printf("service thread budget (before renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_budget.tv_sec,
+// current_serv_thread_budget.tv_nsec);
+// printf("service thread period (before renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_period.tv_sec,
+// current_serv_thread_period.tv_nsec);
+//
+// err=frsh_rtep_service_thread_vres_renegotiate
+// (FRSH_RESOURCE_ID_DEFAULT,
+// &rtep_serv_thread_budget,
+// &rtep_serv_thread_period,
+// &serv_thread_renegotiation_accepted);
+// assert(err == 0);
+//
+// if (serv_thread_renegotiation_accepted) {
+// printf("service_thread renegotiation accepted\n");
+// } else {
+// printf("service_thread renegotiation not accepted\n");
+// }
+// assert (err == 0);
+//
+// err=frsh_rtep_service_thread_vres_get_budget_and_period
+// (FRSH_RESOURCE_ID_DEFAULT,
+// ¤t_serv_thread_budget,
+// ¤t_serv_thread_period);
+// assert(err == 0);
+// printf("service thread budget (after renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_budget.tv_sec,
+// current_serv_thread_budget.tv_nsec);
+// printf("service thread period (after renegotiation): sec=%d nsec=%d\n",
+// current_serv_thread_period.tv_sec,
+// current_serv_thread_period.tv_nsec);
+
+ printf("\nEND of the TEST\n");
+ return 0;
}