/**
 * @file vars.h
 *
 * @brief Global variables and constants.
 *
 * Copyright 2007-2008, Freie Universitaet Berlin. All rights reserved.
 * Please refer to the COPYING file for detailed licensing information.
 *
 * @author Georg Wittenburg
 *
 * $Id: vars.h 2685 2008-06-25 16:38:56Z wittenbu $
 */

#ifndef VARS_H
#define VARS_H

#include <stdio.h>
#include <stdlib.h>

#include "types.h"
#include "rudp-light/rudp-light_vars.h"



#define C_ERROR_NOT_SET			0x0	///< Error code not set (must not happen).
#define C_ERROR_OK			0x1	///< No error, everything OK.
#define C_ERROR_PARAMETER		0x2	///< Error due to invalid parameter.
#define C_ERROR_NOT_FOUND		0x3	///< Error due to requested resource not being found.
#define C_ERROR_TIMEOUT			0x4	///< Error due to timeout.
#define C_ERROR_OUT_OF_MEMORY		0x5	///< Error due to lack of memory.
#define C_ERROR_BUSY			0x6	///< Error due to a component being busy.
#define C_ERROR_IN_PROGRESS		0x7	///< Error due to a similar request already being in progress.
#define C_ERROR_COMM_ERROR		0x8	///< Error due to a communication error.
#define C_ERROR_REMOTE_BUSY		0x9	///< Error due to the remote component / node being busy.



/**
 * @brief Global constant to enable debugging.
 */
#define C_ENABLE_DEBUG

#ifdef C_ENABLE_DEBUG
	#define C_DEBUG_LEVEL_NONE		0x0	///< No debug level given.
	#define C_DEBUG_LEVEL_FATAL		0x1	///< Debug level for fatal errors.
	#define C_DEBUG_LEVEL_ERROR		0x2	///< Debug level for regular errors.
	#define C_DEBUG_LEVEL_WARN		0x3	///< Debug level for warnings.
	#define C_DEBUG_LEVEL_NOTE		0x4	///< Debug level for important notes.
	#define C_DEBUG_LEVEL_INFO		0x5	///< Debug level for regular information.
	#define C_DEBUG_LEVEL_DEBUG		0x6	///< Debug level for debug output.
	#define C_DEBUG_LEVEL_VERBOSE		0x7	///< Debug level for verbose debug output.

	/**
	 * @brief Current debug level.
	 */
	#define C_DEBUG_LEVEL			C_DEBUG_LEVEL_INFO

	/**
	 * @brief Debug output function macro (enabled)
	 */
	#define C_DEBUG			debug_printf
#else
	/**
	 * @brief Debug output function macro (disabled)
	 */
	#define C_DEBUG			if(0) debug_printf
#endif	// C_ENABLE_DEBUG



/**
 * @brief Flag whether consistency checks should be performed when shutting
 * down.
 */
bool C_check_consistency_on_shutdown;

/**
 * @brief List of pending callbacks.
 */
list_t* C_callbacks;

/**
 * @brief Unique identifier for the next callback.
 */
uint16_t C_next_callback_id;

/**
 * @brief Number of registered callbacks.
 */
uint32_t C_registered_callbacks;

/**
 * @brief Number of executed callbacks.
 */
uint32_t C_executed_callbacks;



/**
 * @brief Convenience macro for address of the local node.
 */
#define C_LOCAL_ADDR			C_local_addr

/**
 * @brief Address of the local node.
 */
C_addr_t C_local_addr;



#ifndef ARCH_NS2

/**
 * @brief Default UDP port number.
 */
#define C_DEFAULT_UDP_PORT	8380

/**
 * @brief UDP socket handle.
 */
int C_udp_socket;

#endif	// ARCH_NS2



/**
 * @brief Maximum transmission unit (MTU) in bytes.
 */
#define C_MTU				1500

/**
 * @brief Expected network diameter.
 */
#define C_EXPECTED_NETWORK_DIAMETER	16

/**
 * @brief Default time-to-live (TTL) for transmitted packets.
 */
#define C_DEFAULT_TTL			C_EXPECTED_NETWORK_DIAMETER

/**
 * @brief Expected single-hop round trip time.
 *
 * Expected round trip time (RTT) for single-hop packet transmission in
 * seconds.
 */
#define C_EXPECTED_SINGLE_HOP_RTT	0.2

/**
 * @brief Expected multi-hop round trip time.
 *
 * Expected round trip time (RTT) for multi-hop packet transmission in
 * seconds. This value must be greater than 1.0 because it is used as base when
 * calculating the exponential backoff time.
 */
#define C_EXPECTED_MULTI_HOP_RTT	(C_EXPECTED_SINGLE_HOP_RTT * C_EXPECTED_NETWORK_DIAMETER)

/**
 * @brief Expected time to establish a new route in seconds.
 */
#define C_ROUTE_ESTABLISHMENT_TIME	(2.0 * C_EXPECTED_MULTI_HOP_RTT)

/**
 * @brief Expected time to allow for all remaining packets in the network to be
 * delivered.
 */
#define C_NETWORK_FLUSH_TIME		(10.0 * C_EXPECTED_MULTI_HOP_RTT)

/**
 * @brief Timeout for higherlevel protocols.
 *
 * It should allow for enough time for RUDP to transmit and acknowledge a
 * packet under normal network conditions.
 */
#define C_TIMEOUT			((C_RUDP_PACKET_RETRIES + 1) * C_RUDP_MAX_BACKOFF_TIME)

/**
 * @brief Current sequence number for transmitted packets.
 */
uint32_t C_sequence_number;

/**
 * @brief Size of cache for recently received packets.
 */
#define C_RECEIVED_PACKET_CACHE_SIZE	64

/**
 * @brief Cache for recently received packets.
 */
packet_fingerprint_t C_received_packet_cache[C_RECEIVED_PACKET_CACHE_SIZE];



/**
 * @brief Network map.
 *
 * This list is to collect information about all nodes that this node has been
 * in contact with.
 */
list_t* C_network_map;

/**
 * @brief Number of direct (one-hop) neighbors of this node.
 *
 * This variable is only updated on demand.
 */
uint32_t C_direct_neighbors;

/**
 * @brief Length of the longest route leading to this node in hops.
 *
 * This variable is only updated on demand.
 */
uint32_t C_longest_route;

/**
 * @brief Average length of all routes leading to this node.
 *
 * This variable is only updated on demand.
 */
double C_average_route;



/**
 * @brief Maximal supported number of different services.
 *
 * Each service may have multiple instances.
 */
#define C_MAX_SERVICES	4



/**
 * @brief Size of buffer for converting numeric addresses to a string
 * representation.
 *
 * With a buffer size of 8 we are definately on the safe side. Less is
 * probably OK, too, especially when running on memory constrained devices.
 */
#define C_ADDR_TO_STR_BUFFER_SIZE	8

/**
 * @brief Length of strings in buffer for converting numeric addresses to a
 * string representation.
 *
 * This has to be big enough to support an IPv4 address in the dotted decimal
 * notation, but may be smaller on platforms with other addressing schemes.
 */
#define C_ADDR_TO_STR_BUFFER_STR_LEN	16

/**
 * @brief Buffer for converting numeric addresses to a string representation.
 *
 * Multiple address strings may need to be valid at the same point in time,
 * e.g. when printing debugging output. Hence, we need a buffer with multiple
 * slots to avoid overwriting strings that still need to be processed.
 */
char C_addr_to_str_buffer[C_ADDR_TO_STR_BUFFER_SIZE][C_ADDR_TO_STR_BUFFER_STR_LEN];

/**
 * @brief Currently used index of buffer for converting numeric addresses to a
 * string representation.
 */
uint8_t C_addr_to_str_buffer_index;



/**
 * @brief Number of ERRORs encountered during execution.
 */
uint32_t C_DEBUG_ERRORs;

/**
 * @brief Number of WARNings encountered during execution.
 */
uint32_t C_DEBUG_WARNs;

#endif	// VARS_H
