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

#ifndef TYPES_H
#define TYPES_H



#ifdef ARCH_NONE
	// Used when generating dependencies.
#elif defined(ARCH_LINUX)
	#include "arch/linux/types.h"
#elif defined(ARCH_WIN32)
	#include "arch/win32/types.h"
#elif defined(ARCH_NS2)
	// Nothing to do.
#else
	#error No architecture defined (available architectures are: ARCH_LINUX, ARCH_WIN32 and ARCH_NS2).
#endif	// ARCH_*



#include <stdlib.h>
#include <string.h>



/**
 * @brief Wrapper macro around malloc().
 *
 * Allocates memory and initializes it to 0x0. Aborts if no memory was
 * available.
 *
 * @param p Pointer at which memory is to be allocated.
 * @param type Type of data structure.
 */
#define MALLOC(p, type) \
	p = (type*) malloc(sizeof(type)); \
	if(p == NULL) { \
		printf("Unable to allocate memory.\n"); \
		abort(); \
	} \
	memset(p, 0, sizeof(type))

/**
 * @brief Wrapper macro around malloc() for allocating arrays.
 *
 * @param p Pointer at which memory is to be allocated.
 * @param type Type of data structure.
 * @param count Number of items of the data structure that are to fit into the
 * allocated memory.
 */
#define MALLOC_ARRAY(p, type, count) \
	p = (type*) malloc(sizeof(type) * count); \
	if(p == NULL) { \
		printf("Unable to allocate memory.\n"); \
		abort(); \
	} \
	memset(p, 0, sizeof(type) * count)

/**
 * @brief Wrapper macro around free().
 *
 * Frees memory and sets the pointer to NULL.
 *
 * @param p Pointer to memory.
 */
#define FREE(p) \
	free(p); \
	p = NULL

/**
 * @brief Join two memory regions.
 *
 * Join two memory regions into a newly allocated memory region of the combined
 * size.
 *
 * @param p Pointer at which memory is to be allocated.
 * @param type Type of data structure.
 * @param p1 Pointer to first memory region.
 * @param size1 Size of first memory region.
 * @param p2 Pointer to second memory region.
 * @param size2 Size of second memory region.
 */
#define MALLOC_JOIN(p, type, p1, size1, p2, size2) \
	{ \
		char* tmp = NULL; \
		if(sizeof(type) > (size1 + size2)) { \
			printf("Size of type of joined memory region is greater than allocated memory.\n"); \
			abort(); \
		} \
		MALLOC_ARRAY(tmp, char, size1 + size2); \
		p = (type*) tmp; \
		memcpy(p, p1, size1); \
		memcpy(((char*) p) + size1, p2, size2); \
	}



/**
 * @brief Item of a single-linked list.
 */
typedef struct _list_item {
	void*			data;		///< Pointer to data of this list item.
	struct _list_item*	next;		///< Pointer to next list item.
} _list_item_t;

/**
 * @brief Single-linked list with some extra fields for efficiency.
 */
typedef struct {
	_list_item_t*		first_item;	///< Pointer to first item of the list.
	_list_item_t*		last_item;	///< Pointer to last item of the list.
	uint16_t 		size;		///< Number of items in the list.
} list_t;



/**
 * @brief Callback parameter type.
 */
typedef void* callback_parameter_t;

/**
 * @brief Callback function type.
 */
typedef void(*callback_function_t)(callback_parameter_t);

/**
 * @brief Callback consisting of function, parameter and time.
 */
typedef struct {
	uint16_t		id;		///< Unique ID of this callback.
	callback_function_t	function;	///< Callback function.
	callback_parameter_t parameter;		///< Callback parameter.
	C_time_t		time;		///< Time at which the callback function will be called.
} callback_t;

/**
 * @brief Callback error code function type.
 */
typedef uint8_t C_errno_t;



#define APP_TYPE_ICMP		0x0	///< Packets for the ICMP component.
#define APP_TYPE_RUDP		0x1	///< Packets for the RUDP component.
#define APP_TYPE_SLP		0x2	///< Packets for the SLP component.
#define APP_TYPE_SERVICE	0x3	///< Packets for the SERVICE component.
#define APP_TYPE_PLACEMENT	0x4	///< Packets for the PLACEMENT component.
#define APP_TYPE_GRAPHS		0x5	///< Packets for the GRAPHS component.

/**
 * @brief Time-to-live (TTL) type.
 */
typedef uint8_t ttl_t;

/**
 * @brief Sequence number type.
 */
typedef uint16_t seqno_t;

/**
 * @brief Packet header.
 */
typedef struct {
	C_addr_t	from;		///< Source address.
	C_addr_t	to;		///< Destination address.
	uint8_t		hops;		///< Number of times this packet was forwarded.
	C_addr_t	last_hop;	///< Address of last node that forwarded this packet.
	ttl_t		ttl;		///< Time-to-live (TTL).
	seqno_t		seqno;		///< Sequence number.
	uint8_t		app;		///< Application identifier.
	uint8_t		type;		///< Application-specific packet type identifier.
	size_t		payload_length;	///< Size of the payload in bytes.
} packet_header_t;

/**
 * @brief Packet consisting of header and payload.
 */
typedef struct {
	packet_header_t*	header;		///< Pointer to packet header.
	void*			payload;	///< Pointer to packet payload.
} C_packet_t;



/**
 * @brief Packet fingerprint.
 *
 * This data structure is used for checking for duplicates in recently arrived
 * packets.
 */
typedef struct {
	C_time_t	time;			///< Time of arrival.
	C_addr_t	from;			///< Source address.
	seqno_t		seqno;			///< Sequence number.
} packet_fingerprint_t;



/**
 * @brief Basic information about a node in the network.
 */
typedef struct {
	C_addr_t	address;		///< Node address.
	uint8_t		hops;			///< Distance in hops.
	C_addr_t	last_hop;		///< Address of last hop.
	uint32_t	packets;		///< Number of packtes received from this node.
} node_t;

#endif	// TYPES_H
