/*

                                   _JNJ`                        
                               .JNMH`                           
                              JMMF`       `;.                   
                            .NMM)          `MN.                 
                            MMM)            (MML                
                           (MMM`             MMML               
                     M  I  D  N  I  G  H  T    C  o  D  E       
                           (NMMF             MHNH               
                            NMML            .MMM                
                             NMML          .NMH                 
                              4MMNL       .#F                   
                               `4HNNL_   `                      
                                   `"""`                        

                          Copyright (C) 2004-2007
       "Ian (Larry) Latter" <ian dot latter at midnightcode dot org>

    Midnight Code is a registered trademark of Ian Latter.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, and mirrored at the Midnight Code web
    site; as at version 2 of the License only.
  
    This program 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
    General Public License for more details.
  
    You should have received a copy of the GNU General Public License
    (version 2) along with this program; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA, or see http://midnightcode.org/gplv2.txt

*/


/* midnightcode-cast.h :: Midnight Code casting protocol library	*/


#ifndef __MIDNIGHTCODE_CAST_H
#define __MIDNIGHTCODE_CAST_H 1


#define MIDNIGHTCODE_CAST_CACHE_SIZE 50
#define MIDNIGHTCODE_CAST_CACHE_TIME_VARIANCE 2
#define MIDNIGHTCODE_CAST_MESSAGE_MINSIZE 48
#define MIDNIGHTCODE_CAST_SOCKET_QUEUE 5
#define MIDNIGHTCODE_CAST_SOCKET_HANG_MAX 2
#define MIDNIGHTCODE_CAST_POLL_TIME_HANDLER_OUTBOUND 10000000
#define MIDNIGHTCODE_CAST_POLL_TIME_HANDLER_INBOUND 500000
#define MIDNIGHTCODE_CAST_PORT 39

#define MIDNIGHTCODE_CAST_POLL_INTERVAL 10

enum midnightcode_cast_membrane_t
{
  MIDNIGHTCODE_CAST_MEMBRANE_ENCODE = 0,
  MIDNIGHTCODE_CAST_MEMBRANE_DECODE = 1
};

enum midnightcode_cast_query_t
{
  MIDNIGHTCODE_CAST_QUERY_ACK = 1,
  MIDNIGHTCODE_CAST_QUERY_GET = 2,
  MIDNIGHTCODE_CAST_QUERY_SET = 4,
  MIDNIGHTCODE_CAST_QUERY_CONTROL = 8,
  MIDNIGHTCODE_CAST_QUERY_DATA = 16
};

enum midnightcode_cast_type_t
{
  MIDNIGHTCODE_CAST_TYPE_ACK = 1,
  MIDNIGHTCODE_CAST_TYPE_CONTROL,
  MIDNIGHTCODE_CAST_TYPE_DATA
};

enum midnightcode_cast_option_t
{
  MIDNIGHTCODE_CAST_OPTION_UNICAST = 0,
  MIDNIGHTCODE_CAST_OPTION_MULTICAST = 1
};

struct midnightcode_cast_element_t
{
  int gateway;
  struct in_addr ipv4_address;
  char ipv4_address_s[32];
  int port;
  int retrieved;
  int dispatched;
  int timestamp;
  int buffer_size;
  char * buffer;
  midnightcode_list_entry(midnightcode_cast_element_t)
};

midnightcode_list_head(midnightcode_cast_head_t,
                       midnightcode_cast_element_t)

int midnightcode_cast_read(
                     struct midnightcode_cast_head_t * cache,
                     char * address_s, int * timestamp,
                     char ** buffer, int * buffer_size);
int midnightcode_cast_write(
                     struct midnightcode_cast_head_t * cache,
                     char * buffer, int buffer_size);
int midnightcode_cast_seed(
                     struct midnightcode_cast_head_t * cache,
                     char * address_s, int port,
                     char * buffer, int buffer_size);
int midnightcode_cast_cache_empty(struct midnightcode_cast_head_t * cache);
int midnightcode_cast_cache_trim(struct midnightcode_cast_head_t * cache);
int midnightcode_cast_cache_merge(
                     struct midnightcode_cast_head_t * cache,
                     struct midnightcode_cast_head_t * new_cache);
int midnightcode_cast_membrane(int direction, int type,
                     char ** buffer, int * buffer_size,
                     struct midnightcode_cast_element_t ** message_p,
                     struct midnightcode_cast_head_t * cache_items);
int midnightcode_cast_send(
                     struct midnightcode_cast_head_t * cache,
                     struct midnightcode_socket_element_t * socket);
int midnightcode_cast_receive(
                     struct midnightcode_cast_head_t * cache,
                     struct midnightcode_socket_element_t * socket);
void * midnightcode_cast_handler_inbound(void *arg);
void * midnightcode_cast_handler_outbound(void *arg);
int midnightcode_cast_initialise(struct midnightcode_cast_head_t * cache,
                     int options, char * address_s, int port);
int midnightcode_cast_shutdown(struct midnightcode_cast_head_t * cache);


#endif
