/* BTP library - Banana Tree Protocol
 * Copyright (C) 1999-2002  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 _B_PACKET_H
#define _B_PACKET_H

#include <glib.h>


#define B_PACKET_PROTOCOL	'B'
#define B_PACKET_VERSION	2
#define B_PACKET_LENGTH(P) (sizeof(BPacket) + g_ntohs((P)->length))


/**
   
   BPacket.  All protocols use this structure.

*/
typedef struct _BPacket		/* 16 bytes long, 32 bit aligned */
{
  guint8  protocol;		/* B_PACKET_PROTOCOL ('B')	*/
  guint8  version;		/* B_PACKET_VERSION (2)		*/
  guint8  type;			/* Packet type			*/
  guint8  subtype;		/* Packet subtype		*/
  guint16 seq;			/* Sequence number		*/
  guint16 length;		/* Length of data		*/
  guint32 source_id;		/* Source ID			*/
  guint32 id;			/* Session ID	 	 	*/

  guint8  data[0];		/* Data				*/

} BPacket;


/**

   Packets specific to BTP.
   
 */


typedef enum 
{ 
  B_PACKET_TYPE_OK,
  B_PACKET_TYPE_ERROR,
   
  B_PACKET_TYPE_HELLO,
  B_PACKET_TYPE_BYE,
   
  B_PACKET_TYPE_UCAST,
  B_PACKET_TYPE_MCAST,		/* 5 */
   
  B_PACKET_TYPE_INFO_REQUEST,
  B_PACKET_TYPE_INFO_REPLY,
   
  B_PACKET_TYPE_JOIN,
  B_PACKET_TYPE_LEAVE,
  B_PACKET_TYPE_SWITCH,		/* 10 */
  B_PACKET_TYPE_SHORTCUT_ADD,
  B_PACKET_TYPE_SHORTCUT_REMOVE,

  B_PACKET_TYPE_LAST,

} BPacketType;


typedef enum 
{ 
  B_PACKET_OK_SUBTYPE_NONE,
  B_PACKET_OK_SUBTYPE_HELLO,
  B_PACKET_OK_SUBTYPE_SWITCH,
  B_PACKET_OK_SUBTYPE_SHORTCUT

} BPacketOkSubtype;


typedef enum 
{ 
  B_PACKET_ERROR_SUBTYPE_NONE,
  B_PACKET_ERROR_SUBTYPE_HELLO,
  B_PACKET_ERROR_SUBTYPE_SWITCH,
  B_PACKET_ERROR_SUBTYPE_SHORTCUT

} BPacketErrorSubtype;


typedef enum 
{ 
  B_PACKET_INFO_SUBTYPE_PING,
  B_PACKET_INFO_SUBTYPE_NEIGHBORS,
  B_PACKET_INFO_SUBTYPE_NODE

} BPacketInfoSubtype;


typedef enum 
{ 
  B_PACKET_SWITCH_SUBTYPE_SIBLING,
  B_PACKET_SWITCH_SUBTYPE_GPARENT

} BPacketSwitchSubtype;



typedef struct _BAddress
{
  gchar* hostname;
  gint 	 port;

} BAddress;



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

#include "b_conn.h"
#include "b_peer.h"
#include "btp_node.h"


BPacket*  b_packet_new (BConn* conn, guint8 type, guint16 length);
BPacket*  b_packet_clone (BPacket* packet);
void	  b_packet_delete (BPacket* packet);

gint 	  b_packet_read (BConn* conn, const gchar* buffer, gint length, BPacket** packet);
gint	  b_packet_write (BPacket* packet, gchar** bufferp);
       	  
gboolean  b_packet_parse_addr (BPacket* pkt, BAddress** addrp);
gboolean  b_packet_parse_addrs (BPacket* pkt, GSList** listp);

BPacket*  b_packet_new_ok (BConn* conn, BPacketOkSubtype subtype);
BPacket*  b_packet_new_error (BConn* conn, BPacketErrorSubtype subtype);

BPacket*  b_packet_new_hello (BConn* conn);
gboolean  b_packet_parse_hello (BPacket* packet, GURL** urlp, 
				gchar** hostnamep, gint* portp);
BPacket*  b_packet_new_ok_hello (BConn* conn);
BPacket*  b_packet_new_bye (BConn* conn);
 	 	  
BPacket*  b_packet_new_ucast (BConn* conn, const void* buffer, guint16 length);
BPacket*  b_packet_new_mcast (BConn* conn, const void* buffer, guint16 length);
 	 	  
BPacket*  b_packet_new_info_request_ping (BConn* conn);
BPacket*  b_packet_new_info_reply_ping (BConn* conn, BPacket* ping);
       	  
BPacket*  b_packet_new_info_request_neighbors (BtpNode* node);
BPacket*  b_packet_new_info_reply_neighbors (BtpNode* node, BtpNode* parent, GSList* children /* BtpNode */);
gboolean  b_packet_parse_info_reply_neighbors (BPacket* pkt, BAddress** parent, GSList** children /* BAddress */);
	  
BPacket*  b_packet_new_info_reply_node (BConn* conn, BtpNode* me);
gboolean  b_packet_parse_info_reply_node (BPacket* pkt, guint32* delay, gchar** hostname, guint* port);

BPacket*  b_packet_new_join (BtpNode* node);
BPacket*  b_packet_new_switch (BtpNode* node, BtpNode* parent, BPacketSwitchSubtype sub);
gboolean  b_packet_parse_switch (BPacket* pkt, BAddress** addr);
BPacket*  b_packet_new_leave (BtpNode* node);

gchar* 	  b_packet_type_to_string (gint type);

void	  b_address_delete (BAddress* addr);
void	  b_addresses_delete (GSList* addr);

#endif /* _B_PACKET_H */



syntax highlighted by Code2HTML, v. 0.9.1