/* BTP library - Banana Tree Protocol
 * Copyright (C) 1999-2001  The Regents of the University of Michigan
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */

#ifndef _BTP_TREE_H
#define _BTP_TREE_H


#include <glib.h>
#include <gnet/gnet.h>

#include "btp.h"
#include "btp_node.h"
#include "b_packet.h"
#include "b_group.h"


typedef struct _BtpTree BtpTree;


/**

   Callbacks

   These callbacks provide an interface for BTP to communcate with
   higher level protocols.  Set the callbacks by modifying the BtpTree
   structure.

   The read callbacks (mcast and ucast) are called when there's data
   to be read.  The data is passed in the buffer and should be copied
   and read immediately.  BTP OWNS THE DATA - DO NOT DELETE IT.

   The error callback is called if there is an error.  The details
   haven't been figured out yet.

   The packet callback is called when a packet is received.  Return
   TRUE if you have fully processed the packet and BTP should process
   it no more; FALSE if BTP should process it.  This is not used.

*/

typedef void (*BtpTreeMcastReadFunc)(BtpTree* tree, BtpNode* from_node,
				     guint8* buffer, guint length, 
				     gpointer user_data);


typedef void (*BtpTreeUcastReadFunc)(BtpTree* tree, BtpNode* from_node, 
				     guint8* buffer, guint length,
				     gpointer user_data);

typedef void (*BtpTreeErrorFunc)(BtpTree* tree, gpointer user_data);

typedef void (*BtpTreePacketFunc)(BtpTree* tree, BtpNode* node, 
				  BPacket* packet, gpointer user_data);



#define SEQ_CACHE_LEN	100


/**

   BtpTree represents a multicast tree.  Call btp_connect_root to
   create one.

 */
struct _BtpTree
{
  BGroup group;			/* Group info (url, peer)		 */
  gboolean passive;		/* Am I a passive member (I don't join)  */
  gboolean is_deleting;		/* Is the tree being deleted? 		 */

  BtpNode* me;			/* Me					 */
  BtpNode* root;		/* Root (might be me)			 */
  BtpNode* parent;		/* My parent (might be NULL)		 */
  BtpNode* gparent;		/* Grandparent (might be NULL)		 */
  GSList*  children;		/* List of children (subset of nodes)	 */
  GSList*  siblings;		/* List of siblings (subset of nodes)	 */
  GSList*  nodes;		/* List of all nodes 			 */

  /* Switching */
  BtpNode* new_parent;		/* Parent I am switching too		 */
  guint switch_timeout;		/* Timeout on switch to new parent 	 */

  guint request_neighbors_timeout;/* Timeout to request neighbors	 */
  guint find_new_parent_timeout;  /* Timeout to find new parent		 */

  /* Shortcuts */
  GSList* shortcuts;		/* List of shortcuts			 */
  guint find_new_shortcut_timeout; /* Timeout to look for new shortcut   */
  guint send_node_info_timeout;	/* Timeout to mcast info about me	 */
 
  /* Sequence numbers*/
  guint32 seq_cache[SEQ_CACHE_LEN][3];	/* Sequence number cache	 */

  /* Policy */ 
  gint max_degree;		/* Maximum degree (not locally enforced) */
  gboolean follow_nodes;	/* Follow good nodes when they switch	 */
  gboolean use_shortcuts;	/* Add shortcut links			 */
 
  /* Statistics */ 
  guint num_connect;		/* Number of CONNECTs received	 	 */
  guint num_join;		/* Number of JOINs received	 	 */
  guint num_switch;		/* Number of SWITCHs received		 */
  guint num_switch_bad;		/* Number of bad SWITCHes received	 */
  guint num_ok;			/* Number of OKs received		 */
  guint num_error;		/* Number of ERRORs received		 */

  /* Upper level callbacks */
  BtpTreeMcastReadFunc  mcast_read_func;
  BtpTreeUcastReadFunc  ucast_read_func;
  BtpTreeErrorFunc  	error_func;
  BtpTreePacketFunc 	packet_func;

  gpointer 	    	mcast_read_user_data;	/* TODO: Unify? */
  gpointer 	    	ucast_read_user_data;
  gpointer	    	error_user_data;
  gpointer	    	packet_user_data;

};



/* **************************************** */


BtpTree* btp_tree_new (BPeer* peer, GURL* url); /* owns url */
void 	 btp_tree_delete (BtpTree* tree);
void	 btp_tree_print (FILE* file, BtpTree* tree);


/* **************************************** */

gboolean btp_tree_is_me (BtpNode* node);
gboolean btp_tree_is_root (BtpNode* node);
gboolean btp_tree_is_parent (BtpNode* node);
gboolean btp_tree_is_gparent (BtpNode* node);
gboolean btp_tree_is_sibling (BtpNode* node);
gboolean btp_tree_is_child (BtpNode* node);
gboolean btp_tree_is_shortcut (BtpNode* node);
gboolean btp_tree_is_new_parent (BtpNode* node);
gboolean btp_tree_is_one_hop (BtpNode* node);
gboolean btp_tree_is_two_hop (BtpNode* node);
gboolean btp_tree_is_tree_neighbor (BtpNode* node);
gboolean btp_tree_is_mesh_neighbor (BtpNode* node);
gchar*   btp_tree_relation_to_string (BtpNode* node);

void	 btp_tree_add_sibling (BtpNode* node);
void	 btp_tree_remove_sibling (BtpNode* node);
	    
void	 btp_tree_add_child (BtpNode* node);
void	 btp_tree_remove_child (BtpNode* node);

void	 btp_tree_add_shortcut (BtpNode* node);
void     btp_tree_remove_shortcut (BtpNode* node);

guint    btp_tree_degree (BtpTree* tree);
guint    btp_tree_parent_degree (BtpTree* tree);

gboolean btp_tree_is_node (BtpNode* node);
void	 btp_tree_add_node (BtpNode* node);
void	 btp_tree_remove_node (BtpNode* node);
BtpNode* btp_tree_find_node (BtpTree* tree, gchar* hostname, gint port);

void	 btp_tree_send_mcast (BtpTree* tree, const void* buffer, guint16 length);
void	 btp_tree_forward_mcast (BtpTree* tree, BtpNode* not_node, BPacket* pkt);
void	 btp_tree_send_ucast (BtpTree* tree, BtpNode* node, const void* buffer, guint16 length);


/* **************************************** */


#endif /* _BTP_TREE_H */


syntax highlighted by Code2HTML, v. 0.9.1