// Visual Tools S.A. SPAIN
// Rapita Systems Ltd UK
// Evidence ITALY
-//
+//
// See http://www.frescor.org for a link to partners' websites
//
// FRESCOR project (FP6/2005/IST/5-034026) is funded
//
//
// based on previous work (FSF) done in the FIRST project
-//
+//
// Copyright (C) 2005 Mälardalen University, SWEDEN
// Scuola Superiore S.Anna, ITALY
// Universidad de Cantabria, SPAIN
// **//// /**///** ////////** /**//////**
// ** /** //** /** /** /**
// ** /** //** ******** /** /**
-// // // // //////// // //
+// // // // //////// // //
//
// FRSH(FRescor ScHeduler), pronounced "fresh"
//==============================================
#ifndef _FRSH_DISTRIBUTED_H_
#define _FRSH_DISTRIBUTED_H_
+/**
+ * @file frsh_distributed.h
+ **/
+
+
#include "frsh_distributed_types.h"
#include "frsh_core_types.h"
* This module defines the functions and typedefs for use in
* distributed applications.
*
- * Each network is identified by its network_id and FRSH hides its
+ * Each network is identified by its resource_id and FRSH hides its
* characteristics completely. The type of network is implied with
* its ID via a configuration table defined at compile time.
*
* FRSH uses the "message" as the atomic unit for every exchange.
* Queue sizes are measured in number of pending messages.
*
- * A message is composed of one or two packets of the underlying
- * protocol. FRSH provides function calls to get the maximum number
- * of packets in a message, the maximum number of bytes in a packet
- * and the time required to send one packet. With this data the
- * application can compute the budget (transmission time) that she
- * needs and place it in a contract.
+ * FRSH provides a function to calculate the transmision time needed
+ * for a certain message size in a network as well as the maximum
+ * message size that can admit.
+ *
+ * Note also that package delivery guarantee is protocol dependent.
+ * For protocols in which the order is no guaranteed, the application
+ * needs to add extra info to detect possible package disorder.
*
* Summary of typical steps.
*
* 1. Map (internally in FRSH implementation)
- * - node--> node_addresses
- * - network --> network_id's
+ * - node--> network_addresses
+ * - network --> resource_id's
* - unidirectional communication channel --> stream_id
* - other config --> protocol_info.
*
- * 2. One of the nodes (which one is protocol-dependent) negotiates a
- * "network contract" per communication channel that is used in
- * the application. In each contract it is specified:
- * - frsh_resource_type = FRSH_RT_NETWORK.
- * - frsh_resource_id = <network id #>
- * - budget: Time needed to send the require data per period.
+ * 2. In a sending node:
+ * 2.1. Negotiates a "network contract" per communication channel
+ * that is used in the application. In the contract it is
+ * specified:
+ * - frsh_resource_type = FRSH_RT_NETWORK.
+ * - frsh_resource_id = <network id #>
+ * - budget: Time needed to send the required data per period.
* (you can use frsh_netinfo_*() functions for this).
- * - period: Period of sendings.
- * - Other protocol dependent function in protocol_contract_info.
- *
- * 3. In a sending node:
- * 3.1. Create a send_endpoint per any unidirectional stream that will
+ * - period: Period of sendings.
+ * - Queueing info: How will sends be queued at sendEndpoint.
+ * - Other protocol dependent function in protocol_contract_info.
+ * 2.2. Create a send_endpoint per any unidirectional stream that will
* be used in sending
- * network_id --> the network through which the stream will
+ * resource_id --> the network through which the stream will
* flow (this is extra info needed for coherency
* with the bind).
- * destinator --> node_address of the receiver.
+ * destinator --> network_address of the destination.
* stream_id --> the unidirectional communication channel.
- * 3.2. Bind the send_endpoint to the network contract negotiated
+ * 2.3. Bind the send_endpoint to the network contract negotiated
* above.
- * 3.3. The (processor) sending vres invokes frsh_send_(a)sync() to
+ * 2.4. The (processor) sending vres invokes frsh_send_(a)sync() to
* send the data through the corresponding stream.
*
- * 4. In a receiving node:
- * 4.1. Create a receive_endpoint per any unidirectional stream
+ * 3. In a receiving node:
+ * 3.1. Create a receive_endpoint per any unidirectional stream
* that will be used in receiving.
- * 4.2. The processor expecting a reception of message invokes
+ * 3.2. The processor expecting a reception of message invokes
* frsh_receive_(a)sync() to read the incoming data.
*
- * 5. When all comunication is finished and the channel is no longer
+ * 4. When all comunication is finished and the channel is no longer
* needed the nodes will destroy the send and receive endpoints
* and the network contract will be canceled.
**/
-#define FRSH_DISTRIBUTED_MODULE_SUPPORTED 1
+/**
+ * frsh_distributed_init(void)
+ *
+ * This operation initializes all the installed networks and the structures
+ * that are necessary for the distributed module. Currently it is called by
+ * frsh_init so it is not necessary that the user calls it again.
+ *
+ * 0: No error \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ *
+ **/
+int frsh_distributed_init(void);
//////////////////////////////////////////////////////////////////////
// CONTRACT ASPECTS
**/
/**
- * frsh_netinfo_get_packet_tx_time()
+ * frsh_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
+ * 'resource_id' and sending it to 'destination'.
+ *
+ * If the application needs to send bigger messages it will have to
+ * split them.
+ *
+ * Some protocols, like IP, are capable of sending large messages
+ * (and use fragmentation internally) but other protocols don't.
+ *
+ * @param[in] resource_id The network we want the tx time from.
+ * @param[in] destination The destination address
+ * @param[out] max_size The maximum number of bytes for each message
+ *
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or destination is
+ * invalid \n
+ *
+ **/
+int frsh_network_get_max_message_size
+ (const frsh_resource_id_t resource_id,
+ const frsh_network_address_t destination,
+ size_t *max_size);
+
+/**
+ * frsh_network_bytes_to_budget()
*
- * This operation gives the transmission time that it takes to send a
- * packet of the maximum size through the network designated by
- * network_id, when there is no contention, but including any network
- * overheads.
+ * This operation converts a number of bytes into a temporal budget for
+ * a specific network. Network overheads are not included here but are
+ * considered internally when negotiating a specific contract.
*
- * It must be used by the application to calculate the minimum and
- * maximum budgets used in the preparation of network contracts.
+ * @param[in] resource_id The network
+ * @param[in] nbytes Number of bytes
+ * @param[out] budget The network budget for nbytes
*
- * The effective network utilization budget (usually called bandwidth)
- * is always assigned as a number of packets per time unit, so the
- * time used in the negotiation of contracts will be internally
- * transformed into the corresponding necessary number of packets.
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or nbytes is less
+ * than zero \n
*
- * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
- * identifier or if budget is a NULL pointer.
**/
-int frsh_netinfo_get_packet_tx_time
- (frsh_resource_id_t network_id,
- struct timespec *budget);
+int frsh_network_bytes_to_budget
+ (const frsh_resource_id_t resource_id,
+ const size_t nbytes,
+ struct timespec *budget);
/**
- * frsh_netconfig_get_packet_size()
+ * frsh_network_budget_to_bytes()
*
- * This operation gives the maximum number of bytes that can be sent
- * in a packet (MTU) through the network designated by network_id.
+ * This operation converts a temporal budget into a number of bytes for
+ * a specific network. Network overheads are not included.
+ *
+ * @param[in] resource_id The network
+ * @param[in] budget The network budget for nbytes
+ * @param[out] nbytes Number of bytes
*
- * It is usually a configuration value and it helps the user
- * application to calculate the number of packets it will need to
- * reserve for the periodic transmision of its messages and consequently
- * prepare the corresponding contracts.
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL or budget refers to
+ * an invalid time value \n
*
- * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
- * identifier or if packet_size is a NULL pointer.
**/
-int frsh_netinfo_get_max_packet_size
- (frsh_resource_id_t network_id,
- size_t *packet_size);
+int frsh_network_budget_to_bytes
+ (const frsh_resource_id_t resource_id,
+ const struct timespec *budget,
+ size_t *nbytes);
/**
- * frsh_netconfig_get_max_packet_in_msg()
+ * frsh_network_get_min_effective_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
+ * minimum effective budget.
+ *
+ * A negotiated contract, for N bytes in a period T, means that there is a
+ * virtual resource that reserves for the user:
+ *
+ * Ceiling ((N bytes) / budget_to_bytes (min_effective_budget)) "CHUNKS"
+ *
+ * Note that if the user decides not to send these N bytes at once but, say,
+ * one byte at a time, it will consume one "CHUNK" at a time and the reserved
+ * budget will become exhausted before sending all the bytes.
+ *
+ * @param[in] resource_id The network
+ * @param[out] budget The network budget
*
- * This operation is used to obtain the maximum number of packets of
- * which a message can be formed, for the specified network.
+ * @return
+ * FRSH_NO_ERROR \n
+ * FRSH_ERR_INTERNAL_ERROR: protocol dependent internal errors \n
+ * FRSH_ERR_NOT_INITIALIZED: if the protocol is not initialized \n
+ * FRSH_ERR_RESOURCE_ID_INVALID: if resource id does not represent
+ * a network accessible from the current processing node \n
+ * FRSH_ERR_BAD_ARGUMENT: if pointers are NULL \n
*
- * A message is defined as the piece of information used in a send
- * operation. Since the value returned by this operation is measured
- * in packet units, the effective size can be calculated multiplying
- * this value by the size of a packet.
+ **/
+int frsh_network_get_min_effective_budget
+ (const frsh_resource_id_t resource_id,
+ struct timespec *budget);
+
+/**
+ * frsh_contract_set_queueing_info()
*
- * When the value returned by this operation is larger than 1 it means
- * the implementation will make the partition of messages into packets
- * and its recomposition at the receiving node.
+ * This function adds queueing parameters that will be used in the
+ * sendEndpoint when the sendEndpoint is bound to the vres.
+ **/
+int frsh_contract_set_queueing_info(frsh_endpoint_queueing_info_t queueing_info,
+ frsh_contract_t *contract);
+
+/**
+ * frsh_contract_get_queueing_info()
*
- * It returns FRSH_ERR_BAD_ARGUMENT if network_id is not a valid
- * identifier or the pointer max_msg_size is NULL.
+ * This function gets the queueing parameters that were specified in
+ * the network contract.
**/
-int frsh_netinfo_get_max_packet_in_msg
- (frsh_resource_id_t network_id,
- size_t *max_msg_size);
+int frsh_contract_get_queueing_info(const frsh_contract_t *contract,
+ frsh_endpoint_queueing_info_t *queueing_info);
/**
* frsh_contract_set_protocol_info
*
* We get protocol info from the contract
**/
-int frsh_contract_get_protocol_info(frsh_contract_t contract,
+int frsh_contract_get_protocol_info(frsh_contract_t *contract,
frsh_protocol_info_t *protocol_info);
-/*@}*/
+/**
+ * frsh_contract_marshal
+ *
+ * Convert a contract to a sequence of bytes of minimum size so it can
+ * be sent through the network with the minimum amount of bytes.
+ *
+ **/
+
+int frsh_contract_marshal(const frsh_contract_t *contract,
+ unsigned char *buffer,
+ const size_t buffer_size,
+ size_t *size);
+
+/**
+ * frsh_contract_unmarshal
+ *
+ * Convert a sequence of bytes generated by frsh_contract_marshal to a contract
+ *
+ **/
+int frsh_contract_unmarshal(frsh_contract_t *contract,
+ const unsigned char *marshal_bytes,
+ const size_t size);
+/*@}*/
//////////////////////////////////////////////////////////////////////
// TRANSMISSION SERVICES
* These functions allow to create and manage endpoints for sending
* and receiving and to perform send and receive operations both
* synchronously (blocking) and asynchronously (non-blocking).
- *
+ *
* @{
**/
*
* This operation creates a unidirectional stream input endpoint
* through which, after the corresponding binding, it is possible to
- * send data to a unicast or multicast receiver.
+ * send data to a unicast or multicast destination.
*
- * @param[in] network_id Identifier of the network referred in the
+ * @param[in] resource_id Identifier of the network referred in the
* network contract as a resource_id.
- * @param[in] receiver FRSH abstraction of the protocol address for the
+ * @param[in] destination FRSH abstraction of the protocol address for the
* destinator node.
* @param[in] stream_id Identifier of the communication channel between
* the nodes. Multiplexing is achieved by using
* @param[out] endpoint Placeholder for the endpoint object.
**/
int frsh_send_endpoint_create
- (frsh_resource_id_t network_id,
- frsh_node_address_t receiver,
- frsh_stream_id_t stream_id,
- frsh_endpoint_queueing_info_t queueing_info,
- frsh_protocol_info_t protocol_info,
- frsh_send_endpoint_t *endpoint);
+ (frsh_resource_id_t resource_id,
+ frsh_network_address_t destination,
+ frsh_stream_id_t stream_id,
+ frsh_send_endpoint_protocol_info_t protocol_info,
+ frsh_send_endpoint_t *endpoint);
/**
* frsh_send_endpoint_get_params()
* endpoint at creation time.
**/
int frsh_send_endpoint_get_params
- (const frsh_send_endpoint_t *endpoint,
- frsh_resource_id_t *network_id,
- frsh_node_address_t *receiver,
+ (const frsh_send_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
+ frsh_network_address_t *destination,
frsh_stream_id_t *stream,
- frsh_endpoint_queueing_info_t *queueing_info,
- frsh_protocol_info_t *protocol_info
-);
+ frsh_send_endpoint_protocol_info_t *protocol_info);
/**
* frsh_send_endpoint_destroy()
* code.
**/
int frsh_send_endpoint_destroy
- (frsh_send_endpoint_t *endpoint);
+ (frsh_send_endpoint_t endpoint);
/**
* This operation associates a send endpoint with a network vres,
* which means that messages sent through this endpoint will consume
* the vres's reserved bandwidth and its packets will be sent
- * according to the contract established for that vres.
+ * according to the contract established for that vres.
*
* If the endpoint is already bound to another vres, it is effectively
* unbound from it and bound to the specified one. However if a vres
* is already bound to another endpoint an error is returned.
*
- * A consistency check is done in which the network_id specified at
+ * A consistency check is done in which the resource_id specified at
* endpoint creation must correspond to the resource_id of the vres
* contract.
*
- * @return 0 if successful
+ * @return 0 if successful \n
* FRSH_ERR_BAD_ARGUMENT if the endpoint or the vres are not
- * valid
+ * valid \n
* FRSH_ERR_ALREADY_BOUND if the vres is already bound to some
- * other send endpoint.
+ * other send endpoint \n
* FRSH_ERR_WRONG_NETWORK if the vres network id is not the same
- * as the one in the endpoint
+ * as the one in the endpoint \n
**/
int frsh_send_endpoint_bind
(frsh_vres_id_t vres,
- frsh_send_endpoint_t *endpoint);
+ frsh_send_endpoint_t endpoint);
/**
* frsh_send_endpoint_unbind()
*
* This operation unbinds a send endpoint from a vres. Endpoints with
* no vres associated cannot be used to send data, and they stay in
- * that state until they are either eliminated or bound again.
+ * that state until they are either eliminated or bound again.
*
- * @return 0 if successful
- * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
+ * @return 0 if successful \n
+ * FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
**/
int frsh_send_endpoint_unbind
- (frsh_send_endpoint_t *endpoint);
+ (frsh_send_endpoint_t endpoint);
/**
- * frsh_endpoint_get_vres_id()
+ * frsh_send_endpoint_get_vres_id()
*
* This operation copies the id of the vres that is bound to the
- * specified send endpoint into the variable pointed to by vres.
+ * specified send endpoint into the variable pointed to by vres.
*
- * @return 0 if successful
- * FRSH_ERR_NOT_BOUND if the endpoint was not bound.
+ * @return 0 if successful \n
+ * FRSH_ERR_NOT_BOUND if the endpoint was not bound \n
* FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid or vres
- * is NULL
+ * is NULL \n
**/
-int frsh_endpoint_get_vres_id
- (const frsh_send_endpoint_t *endpoint,
+int frsh_send_endpoint_get_vres_id
+ (const frsh_send_endpoint_t endpoint,
frsh_vres_id_t *vres);
/**
- * frsh_send()
+ * frsh_send_async()
*
* This operation sends a message stored in msg and of length size
* through the given endpoint. The operation is non-blocking and
* implement the communications sporadic vres corresponding to the
* network vres bound to the given endpoint.
*
- * Messages sent through the same endpoint are received in the same
- * order in which they were sent.
- *
- * @returns 0 if successful
- * FRSH_ERR_BAD_ARGUMENT if endpoint is not valid
- * FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres
+ * @returns 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if endpoint is not valid \n
+ * FRSH_ERR_NOT_BOUND if endpoint is not bound to a valid vres \n
* FRSH_ERR_TOO_LARGE if the message is too large for the
- * network protocol
+ * network protocol \n
* FRSH_ERR_BUFFER_FULL if the message has been discarded
* because the queue is full (and does not
- * have the policy FRSH_QP_OLDEST.
+ * have the policy FRSH_QP_OLDEST \n
**/
-int frsh_send
- (const frsh_send_endpoint_t *endpoint,
- void *msg,
- size_t size);
+int frsh_send_async
+ (const frsh_send_endpoint_t endpoint,
+ const void *msg,
+ const size_t size);
/**
* frsh_send_sync()
* until the message is processed.
**/
int frsh_send_sync
- (const frsh_send_endpoint_t *endpoint,
+ (const frsh_send_endpoint_t endpoint,
void *msg,
size_t size);
-
-
/**
* frsh_send_endpoint_get_status()
*
* This function tells the number of messages still pending in the
- * endpoint queue together with some optional information which is
- * protocol_dependent.
+ * endpoint queue, whether the network is up or down with some
+ * optional information which is protocol_dependent.
**/
-int frsh_send_endpoint_get_status(const frsh_send_endpoint_t *endpoint,
- int *number_pending_msg,
- frsh_protocol_info_t *protocol_info);
+int frsh_send_endpoint_get_status
+ (const frsh_send_endpoint_t endpoint,
+ int *number_pending_msg,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
/**
* frsh_receive_endpoint_create()
* because don't originate any traffic.
*
* Note that the protocol address is not needed for reception because
- * it can be determined internally by FRSH based on the network_id.
+ * it can be determined internally by FRSH based on the resource_id.
*
* Note also that messages may come from diferent originators.
*
- * @param[in] network_id Id of the network from which we listen.
+ * @param[in] resource_id Id of the network from which we listen.
* @param[in] stream_id Id of the stream within the network.
* @param[in] queueing_info Buffering information(queue size and
* policy).
* application.
* @param[in] endpoin Placeholder for the endpoint object.
*
- * @return 0 if successful
- * FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not valid.
+ * @return 0 if successful \n
+ * FRSH_ERR_BAD_ARGUMENT if the stream or the network id are not
+ * valid \n
**/
int frsh_receive_endpoint_create
- (frsh_resource_id_t network_id,
+ (frsh_resource_id_t resource_id,
frsh_stream_id_t stream_id,
frsh_endpoint_queueing_info_t queueing_info,
- frsh_protocol_info_t protocol_info,
+ frsh_receive_endpoint_protocol_info_t protocol_info,
frsh_receive_endpoint_t *endpoint);
-
/**
* frsh_receive_endpoint_get_params()
*
* endpoint at creation time.
**/
int frsh_receive_endpoint_get_params
- (frsh_resource_id_t *network_id,
+ (const frsh_receive_endpoint_t endpoint,
+ frsh_resource_id_t *resource_id,
frsh_stream_id_t *stream,
frsh_endpoint_queueing_info_t *queueing_info,
- frsh_protocol_info_t *protocol_info,
- const frsh_receive_endpoint_t *endpoint);
+ frsh_receive_endpoint_protocol_info_t *protocol_info);
/**
* frsh_receive_endpoint_destroy()
* code.
**/
int frsh_receive_endpoint_destroy
- (frsh_receive_endpoint_t *endpoint);
+ (frsh_receive_endpoint_t endpoint);
/**
* too small for the message received. In this case the message is
* lost.
*
- * Messages arriving at a receiver buffer that is full will be
+ * Messages arriving at a destination buffer that is full will be
* silently discarded (details in the queueing policy of the
* endpoint). The application is responsible of reading the receive
* endpoints with appropriate regularity, or of using a sequence
- * number or some other mechanism to detect any lost messages.
+ * number or some other mechanism to detect any lost messages.
*
- * @return 0 if successful
+ * @return 0 if successful \n
* FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
- * buffer or message_size are NULL.
+ * buffer or message_size are NULL.\n
* FRSH_ERR_NO_SPACE if the message size is bigger than the
- * provided buffer.
+ * provided buffer \n
**/
int frsh_receive_sync
- (const frsh_receive_endpoint_t *endpoint,
- void *buffer,
+ (const frsh_receive_endpoint_t endpoint,
+ void *buffer,
size_t buffer_size,
- size_t *message_size);
+ size_t *message_size,
+ frsh_network_address_t *from);
/**
- * frsh_receive()
+ * frsh_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
- * returns with error FRSH_NO_MESSAGE.
+ * returns with error FRSH_NO_MESSAGE.
*
- * @return 0 if successful
+ * @return 0 if successful \n
* FRSH_ERR_BAD_ARGUMENT if the endpoint is not valid, or if
- * buffer or message_size are NULL.
- * FRSH_NO_MESSAGE if no messages are available in the queue.
+ * buffer or message_size are NULL \n
+ * FRSH_NO_MESSAGE if no messages are available in the queue \n
* FRSH_ERR_NO_SPACE if the message size is bigger than the
- * provided buffer.
+ * provided buffer \n
**/
-int frsh_receive
- (const frsh_receive_endpoint_t *endpoint,
- void *buffer,
+int frsh_receive_async
+ (const frsh_receive_endpoint_t endpoint,
+ void *buffer,
size_t buffer_size,
- size_t *message_size);
+ size_t *message_size,
+ frsh_network_address_t *from);
/**
* frsh_receive_endpoint_get_status
*
* This function tells the number of messages still pending in the
- * endpoint queue together with some optional information which is
- * protocol_dependent.
+ * endpoint queue, whether the network is up or down and some optional
+ * information which is protocol dependent.
**/
-int frsh_send_endpoint_get_status(const frsh_receive_endpoint_t *endpoint,
- int *number_pending_messages,
- frsh_protocol_info_t *protocol_info);
-
-
+int frsh_receive_endpoint_get_status
+ (const frsh_receive_endpoint_t endpoint,
+ int *number_pending_messages,
+ frsh_endpoint_network_status_t *network_status,
+ frsh_protocol_status_t *protocol_status);
/*@}*/
-
#endif // _FRSH_DISTRIBUTED_H_