#include "frsh.h" /* frsh_resource_id_t, .. */
#include "frescan.h" /* frescan_init, ... */
-#include "frescan_data.h" /* frescan_contract_t, ... */
#include "frescan_bwres.h" /* frescan_bwres_init, ... */
+#include "frescan_types.h"
+#include "frescan_config.h"
#include "fna.h" /* fna_vres_id_t, fna_endpoint_data_t */
-
-#undef ERROR
-#include "frescan_debug.h" /* DEBUG, ERROR */
+#include "frescan_debug.h" /* DEBUG, FRESCAN_ERROR */
+#include "frescan_servers.h"
//////////////////////////////////////////////////////////////////////
// INITIALIZATION
int ret;
frescan_init_params_t init_params;
- // TODO: resource_id must be relative or sth
- // TODO: init_params must be configurable
- init_params.net = (frescan_network_t)resource_id;
- init_params.node = (frescan_node_t)FRSH_CPU_ID_DEFAULT;
- init_params.tx_fp_max_prio = 10;
- init_params.rx_num_of_channels = 10;
- init_params.rx_channel_max_prio = NULL;
+ init_params.net = resource_id - FRESCAN_BWRES_FNA_NET_BASE;
+ init_params.node = FRESCAN_BWRES_FNA_LOCAL_NODE;
+ init_params.tx_fp_max_prio = FRESCAN_BWRES_TX_FP_MX_PRIO;
+ init_params.rx_num_of_channels = FRESCAN_BWRES_RX_NUM_CHANNELS;
+ init_params.rx_channel_max_prio = FRESCAN_BWRES_RX_CHAN_MX_PRIO;
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing FRESCAN\n");
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "Initializing FRESCAN FNA node%u\n", init_params.node);
ret = frescan_init(&init_params);
- if (ret != 0) ERROR ("could not init FRESCAN");
+ if (ret != 0) FRESCAN_ERROR ("could not init FRESCAN");
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "Initializing BWRES\n");
ret = frescan_bwres_init(init_params.net);
- if (ret != 0) ERROR ("could not init BWRES");
+ if (ret != 0) FRESCAN_ERROR ("could not init BWRES");
return 0;
}
// VIRTUAL RESOURCES
///////////////////////////////////////////////////////////////////
+int frescan_fna_group_change_mode_sync
+ (const frsh_resource_id_t resource_id,
+ const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const fna_vres_group_t *vres_to_reneg,
+ const fna_vres_group_t *vres_to_cancel,
+ fna_vres_group_t *new_vres)
+{
+ int ret, i;
+ bool accepted;
+ frescan_ss_group_t ss_to_reneg, ss_to_cancel, ss_new;
+
+ // convert fna_vres to ss
+ if (vres_to_reneg == NULL) {
+ ss_to_reneg.size = 0;
+ } else {
+ ss_to_reneg.size = vres_to_reneg->size;
+ if (ss_to_reneg.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+ FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+ return -1;
+ }
+
+ for(i=0; i<ss_to_reneg.size; i++) {
+ ss_to_reneg.ss[i] =
+ (frescan_ss_t)vres_to_reneg->vres[i];
+ }
+ }
+
+ if (vres_to_cancel == NULL) {
+ ss_to_cancel.size = 0;
+ } else {
+ ss_to_cancel.size = vres_to_cancel->size;
+ if (ss_to_cancel.size > FRESCAN_BWRES_MAX_GROUP_OPS) {
+ FRESCAN_ERROR("FRESCAN_BWRES_MAX_GROUP_OPS small\n");
+ return -1;
+ }
+
+ for(i=0; i<ss_to_cancel.size; i++) {
+ ss_to_cancel.ss[i] =
+ (frescan_ss_t)vres_to_cancel->vres[i];
+ }
+ }
+
+ if ((contracts_to_neg != NULL) && (new_vres == NULL)) {
+ FRESCAN_ERROR("new_vres is NULL\n");
+ return -1;
+ }
+
+ // negotiate
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "calling frescan_bwres_group_change_mode_sync\n");
+
+ ret = frescan_bwres_group_change_mode_sync
+ ((frescan_network_t)resource_id,
+ contracts_to_neg,
+ contracts_to_reneg,
+ &ss_to_reneg,
+ &ss_to_cancel,
+ &ss_new,
+ &accepted);
+ if (ret != 0) return -1;
+
+ if (accepted == false) {
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation not accepted\n");
+ return -1; // TODO: change to constant FNA_REJECTED
+ }
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "negotiation accepted\n");
+ // convert new ss to fna_vres
+ if (contracts_to_neg != NULL) {
+ new_vres->size = ss_new.size;
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "new_vres->size:%d\n", new_vres->size);
+ for(i=0; i<new_vres->size; i++) {
+ new_vres->vres[i] = (fna_vres_id_t)ss_new.ss[i];
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "new_vres->vres[%d]:%u\n", i, new_vres->vres[i]);
+ }
+ }
+
+ return 0;
+}
+
/**
* frescan_fna_contract_negotiate()
*
fna_vres_id_t *vres)
{
int ret;
- bool accepted;
- frescan_ss_t ss;
- frescan_contract_t frescan_contract;
+ frsh_contracts_group_t contracts_to_neg;
+ fna_vres_group_t new_vres;
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
- "frsh contract->frescan contract\n");
+ contracts_to_neg.size = 1;
+ contracts_to_neg.contracts[0] = *contract;
- // NOTE: budget is stored as number of can frames in tv_sec
- frescan_contract.min_values.budget = contract->budget_min.tv_sec;
- frescan_contract.min_values.period = contract->period_max;
+ ret = frescan_fna_group_change_mode_sync
+ (resource_id, &contracts_to_neg, NULL, NULL, NULL, &new_vres);
+ if (ret != 0) return ret;
- frescan_contract.max_values.budget = contract->budget_max.tv_sec;
- frescan_contract.max_values.period = contract->period_min;
-
- // TODO: put 0 if we want the sa module to assign the prios
- frescan_contract.prio = contract->preemption_level;
-
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "calling frescan_bwres_negotiate\n");
- ret = frescan_bwres_negotiate((frescan_network_t)resource_id,
- &frescan_contract,
- &ss,
- &accepted);
- if (ret != 0) return -1;
-
- if (accepted == true) {
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract accepted\n");
- *vres = (fna_vres_id_t)ss;
- return 0;
- } else {
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "contract not accepted\n");
- return -1; // TODO: change to constant FNA_REJECTED
- }
+ *vres = new_vres.vres[0];
+ return 0;
}
/**
const fna_vres_id_t vres,
const frsh_contract_t *new_contract)
{
- ERROR("not implemented\n");
- return -1;
+ frsh_contracts_group_t contracts_to_reneg;
+ fna_vres_group_t vres_to_reneg;
+
+ contracts_to_reneg.size = 1;
+ contracts_to_reneg.contracts[0] = *new_contract;
+ vres_to_reneg.size = 1;
+ vres_to_reneg.vres[0] = vres;
+
+ return frescan_fna_group_change_mode_sync
+ (resource_id, NULL, &contracts_to_reneg,
+ &vres_to_reneg, NULL, NULL);
}
/**
frsh_signal_t signal_to_notify,
frsh_signal_info_t signal_info)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const fna_vres_id_t vres,
frsh_renegotiation_status_t *renegotiation_status)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
(const frsh_resource_id_t resource_id,
const fna_vres_id_t vres)
{
- ERROR("not implemented\n");
- return -1;
+ fna_vres_group_t vres_to_cancel;
+
+ vres_to_cancel.size = 1;
+ vres_to_cancel.vres[0] = vres;
+
+ return frescan_fna_group_change_mode_sync
+ (resource_id, NULL, NULL, NULL, &vres_to_cancel, NULL);
}
/**
const fna_vres_id_t vres,
frsh_contract_t *contract)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const fna_vres_id_t vres,
struct timespec *usage)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const fna_vres_id_t vres,
struct timespec *remaining_budget)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
struct timespec *budget,
struct timespec *period)
{
- ERROR("not implemented\n");
- return -1;
+ int ret;
+ frescan_server_params_t server_params;
+
+ ret = frescan_servers_get_data((frescan_network_t)resource_id,
+ &server_params,
+ (frescan_ss_t)vres);
+ if (ret != 0) return ret;
+
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
+ server_params.budget);
+
+ *period = server_params.period;
+
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "budget(%d packets %ld us\n",
+ server_params.budget, frsh_rel_time_to_usec(*budget));
+
+ return 0;
}
/*@}*/
const int importance,
uint32_t *capacity)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const int importance,
int *total_weight)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const struct timespec new_budget,
const struct timespec new_period)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const void *msg,
const size_t size)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
int ret;
frescan_send_params_t params;
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
"net:%u dest:%u chan:%u size:%u ss:%u\n",
endpoint->resource_id, endpoint->destination,
endpoint->stream_id, size, endpoint->vres);
ret = frescan_send(¶ms, (uint8_t *)msg, size);
if (ret != 0) {
- ERROR ("could not send message\n");
+ FRESCAN_ERROR ("could not send message\n");
return -1;
}
params.channel = (frescan_channel_t)endpoint->stream_id;
params.flags = FRESCAN_SYNC;
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
"net:%u chan:%u size:%u\n",
endpoint->resource_id, endpoint->stream_id, buffer_size);
received_bytes, &frescan_from, &prio);
if (ret != 0) {
- ERROR ("error while receiving message");
+ FRESCAN_ERROR ("error while receiving message");
return -1;
}
*from = (frsh_network_address_t)frescan_from;
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
"msg received, from:%u bytes:%u prio:%u\n",
*from, *received_bytes, prio);
size_t *received_bytes,
frsh_network_address_t *from)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
frsh_endpoint_network_status_t *network_status,
frsh_protocol_status_t *protocol_status)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
int frescan_fna_receive_endpoint_created
(fna_endpoint_data_t *endpoint)
{
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG, "receive endpoint created\n");
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG, "receive endpoint created\n");
return 0;
}
frsh_endpoint_network_status_t *network_status,
frsh_protocol_status_t *protocol_status)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
const frsh_network_address_t destination,
size_t *max_size)
{
- ERROR("not implemented\n");
+ FRESCAN_ERROR("not implemented\n");
return -1;
}
int frescan_fna_network_bytes_to_budget
(const frsh_resource_id_t resource_id,
const size_t nbytes,
- struct timespec *budget)
+ frsh_rel_time_t *budget)
{
int number_of_packets;
return -1;
}
- // we measure the budget in number of FRESCAN frames (8 bytes)
+ // number of FRESCAN frames (8 bytes)
number_of_packets = (int) ceil((double)nbytes / 8.0);
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US *
+ number_of_packets);
- // 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;
-
- DEBUG(FRESCAN_FNA_ENABLE_DEBUG,
- "bytes: %d -> budget: %d\n", nbytes, budget->tv_sec);
+ DEBUG(FRESCAN_BWRES_FNA_ENABLE_DEBUG,
+ "bytes: %d -> budget: %ld us\n",
+ nbytes, frsh_rel_time_to_usec(*budget));
return 0;
}
**/
int frescan_fna_network_budget_to_bytes
(const frsh_resource_id_t resource_id,
- const struct timespec *budget,
+ const frsh_rel_time_t *budget,
size_t *nbytes)
{
int number_of_packets;
return -1;
}
- number_of_packets = budget->tv_sec;
+ number_of_packets = frsh_rel_time_to_usec(*budget) /
+ FRESCAN_FRAME_TX_TIME_US;
*nbytes = number_of_packets * 8;
return -1;
}
- budget->tv_sec = 1;
+ *budget = frsh_usec_to_rel_time((long)FRESCAN_FRAME_TX_TIME_US);
return 0;
}
// GLOBAL variable to install the network protocol in FRESCOR
fna_operations_t frescan_fna_operations = {
+#ifdef FRESCAN_FNA_ENABLED
.fna_init = frescan_fna_init,
+ .fna_group_change_mode_sync = frescan_fna_group_change_mode_sync,
.fna_contract_negotiate = frescan_fna_contract_negotiate,
.fna_contract_renegotiate_sync = frescan_fna_contract_renegotiate_sync,
.fna_contract_renegotiate_async = frescan_fna_contract_renegotiate_async,
.fna_send_endpoint_get_status = frescan_fna_send_endpoint_get_status,
.fna_receive_endpoint_created = frescan_fna_receive_endpoint_created,
.fna_receive_endpoint_get_status = frescan_fna_receive_endpoint_get_status,
+#endif
.fna_network_get_max_message_size = frescan_fna_network_get_max_message_size,
.fna_network_bytes_to_budget = frescan_fna_network_bytes_to_budget,
.fna_network_budget_to_bytes = frescan_fna_network_budget_to_bytes,