--- /dev/null
+/*
+ * test_c_rtep_fna.c
+ *
+ * Goal:
+ *
+ * The goal of this program is to test the RTEP implementation of the functions
+ * defined at fna.h without passing through the FRSH interface.
+ *
+ * Algorithm:
+ *
+ * We have two nodes, a sender and a receiver. The sender negotiates a contract,
+ * send info to the receiver, then renegotiates the contract and finally it
+ * cancels the contract.
+ *
+ */
+
+#include <assert.h> // for assert
+#include <stdio.h> // for printf
+#include <time.h> // for timespec
+
+#include "frsh_core.h" // for frsh_contract_set_xxx
+#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_vres_id_t
+#include "frsh_fna.h" // for frsh_rtep_*
+#include "rtep_fna.h" // for rtep_fna_operations
+
+#include "rtep.h" // for rtep_station_id_t, rtep_channel_t
+
+int main ()
+{
+ int err;
+ rtep_station_id_t me, normal_station, multicast_station;
+ frsh_network_address_t frsh_address;
+ char multicast_name[] = "broadcast";
+ size_t max_size, max_multicast_size, budget_bytes, nbytes;
+ struct timespec budget_timespec, period_max;
+ frsh_contract_t frsh_contract;
+ fna_vres_id_t vres;
+ fna_endpoint_data_t endpoint;
+ const int MSG_BUFFER_MX = 10;
+ char msg_buffer[MSG_BUFFER_MX];
+ int msg_size;
+ int msg_counter;
+
+ printf("--------------------------------------------------\n");
+ printf("1.- fna_init\n");
+ printf("--------------------------------------------------\n");
+ err = frsh_init();
+// err = rtep_fna_operations.fna_init(FRSH_RESOURCE_ID_DEFAULT);
+ assert(err == 0);
+
+ printf("--------------------------------------------------\n");
+ printf("2.- fna_network_get_max_message_size\n");
+ printf("--------------------------------------------------\n");
+ // get broadcast address for FRESCOR
+ multicast_station = rtep_get_station_id_by_name
+ ((uint8_t *)multicast_name, sizeof(multicast_name)-1);
+
+ err = frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, multicast_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a broadcast address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_multicast_size);
+ printf("Max multicast message size: %d\n", max_multicast_size);
+ assert (err == 0);
+ assert (max_multicast_size == MULTICAST_MTU);
+
+ // now the same with a normal address (i.e: 2)
+ normal_station = 2;
+ err=frsh_rtep_map_network_address
+ (FRSH_RESOURCE_ID_DEFAULT, normal_station, &frsh_address);
+ assert (err == 0);
+
+ // maximum size per message for a normal address
+ err=rtep_fna_operations.fna_network_get_max_message_size
+ (FRSH_RESOURCE_ID_DEFAULT, frsh_address, &max_size);
+ printf("Max message size: %d\n", max_size);
+ assert (err == 0);
+ assert (max_size == MAX_RTEP_MTU);
+
+ printf("--------------------------------------------------\n");
+ printf("3.- fna_network_budget_to_bytes\n");
+ printf("--------------------------------------------------\n");
+ nbytes = 1700;
+ err=rtep_fna_operations.fna_network_bytes_to_budget
+ (FRSH_RESOURCE_ID_DEFAULT, nbytes, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("%d user bytes -> %d budget bytes\n", nbytes, budget_bytes);
+
+ printf("--------------------------------------------------\n");
+ printf("4.- fna_network_get_min_effective_budget\n");
+ printf("--------------------------------------------------\n");
+ err=rtep_fna_operations.fna_network_get_min_eff_budget
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec);
+ assert (err == 0);
+
+ err=rtep_fna_operations.fna_network_budget_to_bytes
+ (FRSH_RESOURCE_ID_DEFAULT, &budget_timespec, &budget_bytes);
+ assert (err == 0);
+ printf("Minimum effective budget: %d\n", budget_bytes);
+
+ // send or receive
+ me = rtep_get_station_id();
+
+ if (me == 1) {
+
+ printf("--------------------------------------------------\n");
+ printf("5.- fna_contract_negotiate\n");
+ printf("--------------------------------------------------\n");
+
+ period_max.tv_sec = 3;
+ period_max.tv_nsec = 0;
+
+ // Create the contract
+ frsh_contract.workload = FRSH_WT_INDETERMINATE;
+ frsh_contract.granularity = FRSH_DEFAULT_GRANULARITY;
+ frsh_contract.weight = FRSH_DEFAULT_WEIGHT;
+ frsh_contract.importance = FRSH_DEFAULT_IMPORTANCE;
+ frsh_contract.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ frsh_contract.resource_type = FRSH_RT_NETWORK;
+
+ frsh_contract.budget_min = budget_timespec;
+ frsh_contract.period_max = period_max;
+ frsh_contract.d_equals_t = true;
+ frsh_contract.preemption_level = 4;
+
+ // Negotiate the contract
+ err = rtep_fna_operations.fna_contract_negotiate
+ (FRSH_RESOURCE_ID_DEFAULT, &frsh_contract, &vres);
+ assert (err == 0);
+ printf("Contract accepted\n");
+
+ // Bind the vres to an endpoint
+ endpoint.endpoint_type = FRSH_SEND_ENDPOINT_TYPE;
+ endpoint.vres = vres;
+ endpoint.is_bound = true;
+ endpoint.destination = 2; // only for send_endpoints
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ msg_counter = 0;
+
+ while(1) {
+ sleep(4);
+ printf("sending message\n");
+
+ msg_counter = msg_counter + 1;
+ msg_size = snprintf(msg_buffer, MSG_BUFFER_MX-1, "MSG %d", msg_counter);
+
+ err = rtep_fna_operations.fna_send_async
+ (&endpoint, msg_buffer, msg_size);
+ assert (err == 0);
+ }
+ } else {
+ size_t received_bytes;
+ frsh_network_address_t from;
+
+ endpoint.endpoint_type = FRSH_RECEIVE_ENDPOINT_TYPE;
+ endpoint.is_bound = false;
+ endpoint.resource_id = FRSH_RESOURCE_ID_DEFAULT;
+ endpoint.stream_id = 7;
+
+ while(1) {
+ printf("blocking to receive\n");
+ err = rtep_fna_operations.fna_receive_sync
+ (&endpoint, msg_buffer, MSG_BUFFER_MX, &received_bytes, &from);
+ assert (err == 0);
+
+ msg_buffer[received_bytes] = '\0';
+
+ printf("msg received: %s\n", msg_buffer);
+ }
+ }
+
+ return 0;
+}