/* 45678901234567890123456789012345678901234567890123456790123456789012345 */
/*
 *		Unofficial release 1.3.0
 *	        	B I N G
 *
 */

/* $Id: bing_stats.h,v 1.4 1999/10/16 07:09:58 fgouget Exp $ */

#ifndef _bing_stats_h_
#define _bing_stats_h_

#include "bing_defs.h"
#include "bing_probes.h"
#include "lin_reg.h"

/*
 * The following 'enumeration' describes the possible states 
 * of the minimum RTT field of rtt_stats_t.
 * <ul>
 *   <li>RTT_STATE_OK to RTT_STATE_REDO are exclusive global flags. 
 *     RTT_STATE_OK means the RTT is valid and not scheduled for update. 
 *   <li>RTT_STATE_HINVALID means the RTT is invalid wrt another RTT. When 
 *     in this state the min_rtt field does not indicate the value of 
 *     the current minimum RTT but the upper bound for this RTT.
 *   <li>RTT_STATE_REDO means the RTT is valid but scheduled for update. 
 *   <li>RTT_STATE_LINVALID indicates that the RTT is invalid with regard 
 *     to a link. It is always use together with RTT_STATE_LINVALID1 
 *     and/or RTT_STATE_LINVALID2 which specify the said link, 
 *     respectively the link between hosts h-1 and h, and the link 
 *     between hosts h and h+1. Note that an RTT can be invalid with 
 *     regard to both links and thus RTT_STATE_LINVALID1 and 
 *     RTT_STATE_LINVALID2 form a bitmask.
 */
#define RTT_STATE_OK            0
#define RTT_STATE_HINVALID      1
#define RTT_STATE_LINVALID      2
#define RTT_STATE_REDO          3
#define RTT_STATE_MASK          3

#define RTT_STATE_LINVALID1     4
#define RTT_STATE_LINVALID2     8


/**
 * This structure contains all the information we have gathered on the RTTs 
 * measured for a given host, method and packet size.
 */
typedef struct {
    /**
     * This is the number of RTTs that we successfully measured, i.e. 
     * this does not count the probes that timed out (see nb_dropped for 
     * that). This is also the number of RTTs stored in the samples 
     * array.
     */
    int nb_samples;

    /**
     * This is the number of probes that timed out. Note that nb_samples 
     * plus nb_dropped may be different from the total number of probes sent 
     * because neither counts probes that yielded an invalid result.
     * (But this is something to check).
     */
    int nb_dropped;

    /* Number of bits exchanged for each packet size. Note that this 
     * depends on the packet size but also on the probe method because
     * of the return packet size. Also the size of the exchanged packets is 
     * not the same for the last host when the BP_ECHOREPLY is used because 
     * the last host will always generate an Echo Reply instead of a TTL 
     * Exceeded.
     */
    int nb_bits;

    /**
     * This describes the state of the minimum RTT. It can be valid, 
     * inconsistent or marked for update. See the RTT_STATE_XXX enumeration.
     */
    int state;

    /**
     * This is the minimum RTT that was measured for this particular host, 
     * method and size. This field must be monotonically decreasing, we must 
     * never put in there a value that would be larger than what was there 
     * before. The RTT is in milliseconds.
     */
    double min_rtt;

#ifdef _DEBUG
    /**
     * When we determine that the RTT is invalid we replace the value of min_rtt 
     * by the maximum allowable value. But in debug mode we still want to remember 
     * what was the value before so that we can display it from time to time. So we 
     * store it in this field. The RTT is in milliseconds.
     */
    double min_rtt_sav;
#endif

    /**
     * This is the sum of all the RTTs that have been measured for this host, method 
     * and size. This is used to later compute the mean.
     */
    double sum_rtt;

    /**
     * This is the maximum RTT measured for this host, method and size. This 
     * field must be monotonically increasing. But it is actually never used 
     * except (potentially) for display. The RTT is in milliseconds.
     */
    double max_rtt;

    /* All the RTT values for this {host,method,packet size} */

    /**
     * This is the size of the samples array. This is usually higher than 
     * nb_samples to minimize the number of reallocations.
     */
    int samples_size;

    /**
     * This array stores all the RTTs that have been measured.
     */
    double* samples;
} rtt_stats_t;



/**
 * This structure contains all the data about a given host and method. It 
 * aggregates some statistics gathered for each individual packaet sizes like 
 * the number of dropped packets and also describes how the RTT evolves with 
 * the packet size.
 */
typedef struct {
    /**
     * This array contains the data that was gathered for each packet size 
     * for this particular host, method.
     */
    rtt_stats_t* rtt_stats;

    /**
     * This is the number of RTT samples that have been measured across the packet 
     * sizes.
     */
    int nb_samples;

    /**
     * This is the number of RTT probes that have timed out across the packet 
     * sizes.
     */
    int nb_dropped;

    /**
     * This is the number of RTT samples that are currently in an 'invalid' state
     * across all packet sizes.
     */
    int nb_hinvalid;

    /**
     * This is the number of RTT samples that are currently in an 'invalid' state
     * across all packet sizes.
     */
    int nb_linvalid;

    /**
     * This is the number of RTT samples that are currently in the 'redo' state
     * across all packet sizes.
     */
    int nb_redo;

    /**
     * One of our main goal is to analyze how the RTT evolves when the packet 
     * size changes. Well, we expect it to be linear and this is the result of 
     * the linear regression. Note that this linear regression does not take 
     * into account any RTT that is in one of the 'invalid' states.
     */
    linreg_t host_reg;

    /**
     * This structure describes the characteristics of the network link, either 
     * uplink or uplink and downlink composited together, from the previous host 
     * to this host. This field is not significant for the first host in the list. 
     * These characteristics are computed by doing a linear regression on the 
     * RTT difference between this host and the previous host for each given packet 
     * size. Any RTT which is in the RTT_STATE_HINVALID or the wrong 
     * RTT_STATE_LINVALID is ignored for the purpose of this computation.
     */
    linreg_t link_reg;
} rtt_law_t;


/**
 * This structure contains the data specific to a host.
 */
typedef struct {

    /**
     * This is the name of the host. This is either the name the user gave on the 
     * command line for a 'key host', the name we got back from the DNS or simply 
     * the IP address.
     */
    char* name;

    /**
     * This is the host's IP address. The port field is not significant.
     */
    struct sockaddr address;

    /**
     * This is the ttl of the host or -1 if that information is not known.
     */
    char ttl;

    /**
     * For each probe method, this array contains an entry describing how the 
     * RTT behaves as the packet size changes. Each structure in turn contains 
     * information for each packet size and then each probe.
     */
    rtt_law_t* rtt_laws;
} host_stats_t;



/**
 * This structure regroups all the bing statistics information plus some 
 * other state information that we need to pass around.
 */
typedef struct {
    /**
     * This is the handle we use to send and receive probes.
     */
    bp_handle probe_handle;

    /**
     * Stores the number of probe methods that are in use. This is either 1 or 2.
     */
    int nb_methods;

    /**
     * This array stores the probe methods identifiers.
     */
    int* methods;

    /**
     * This is the number of different packet sizes to be sent for each host 
     * and method.
     */
    int nb_sizes;

    /**
     * This array stores the packet payload sizes in bytes.
     */
    int* packet_sizes;

    /**
     * This is the number of hosts to probe. There must be at least two hosts.
     */
    int nb_hosts;

    /**
     * This array stores the information concerning each host and also the 
     * link characteristics about the link between each listed host.
     */
    host_stats_t* hosts;
} bing_stats_t;



/*
 * More functions for bing statistics
 */

/*
  --------------------------------------------------------------------------
	(!!) update description bs_probe_init initialises the structure holding the information 
	about the RTT samples
  ------------+----+-----+--------------------------------------------------
  Parameter   | IN | OUT | Role
  ------------+----+-----+--------------------------------------------------
  probes      | X  |  X  | Data about the probes for a given size
  size        | X  |  X  | The total number of bytes exchanged
  min_rtt     |    |  X  | The minimum Rtt. This is duplicated from the
              |    |     | data in the probes parameter but is needed for
              |    |     | the linear regression.
  ------------+----+-----+--------------------------------------------------
  RETURN      |    |  X  | No return value
  ------------+----+-----+--------------------------------------------------
*/
extern BINGAPI int BINGPROTO(
    rtt_stats_init,
    (
        rtt_stats_t *rtt_stats
    ));

/*
  (!!) update description
  --------------------------------------------------------------------------
	bs_add_sample takes into account a new sample. It checks that it is 
	the right size, and computes the new minimum RTT.
  ------------+----+-----+--------------------------------------------------
  Parameter   | IN | OUT | Role
  ------------+----+-----+--------------------------------------------------
  probes      | X  |  X  | The number of samples after the sample addition
  size        | X  |  X  | The x value of the sample to add
  min_rtt     |    |  X  | The y value of the sample to add
  ------------+----+-----+--------------------------------------------------
  RETURN      |    |  X  | No return value
  ------------+----+-----+--------------------------------------------------
*/
extern BINGAPI int BINGPROTO(
    rtt_stats_add,
    (
        int size,
        int rtt,
        rtt_stats_t *rtt_stats,
        int *size1,
        double *min_rtt
    ));

extern BINGAPI int BINGPROTO(
    rtt_law_invalidate,
    (
        rtt_law_t *rtt_law,
        int index,
        double max_valid
    ));


extern BINGAPI int BINGPROTO(
    rtt_law_remove_worst_point,
    (
        rtt_law_t *rtt_law,
        int nb_sizes
    ));

/*
  --------------------------------------------------------------------------
	(!!) update description bs_probe_init initialises the structure holding the information 
	about the RTT samples
  ------------+----+-----+--------------------------------------------------
  Parameter   | IN | OUT | Role
  ------------+----+-----+--------------------------------------------------
  probes      | X  |  X  | Data about the probes for a given size
  size        | X  |  X  | The total number of bytes exchanged
  min_rtt     |    |  X  | The minimum Rtt. This is duplicated from the
              |    |     | data in the probes parameter but is needed for
              |    |     | the linear regression.
  ------------+----+-----+--------------------------------------------------
  RETURN      |    |  X  | No return value
  ------------+----+-----+--------------------------------------------------
*/
extern BINGAPI int BINGPROTO(
    rtt_law_init,
    (
        rtt_law_t *rtt_law,
        int nb_sizes
    ));

/* (!!) */
extern BINGAPI int BINGPROTO(
    method_init_probe,
    (
        bp_handle* probe_handle,
        int method
    ));        

extern BINGAPI int BINGPROTO(
    rtt_law_set_rtt_state,
    (
        rtt_law_t *rtt_law,
        int s,
        int state,
        double max_rtt
    ));

/* (!!) */
extern BINGAPI int BINGPROTO(
    method_do_probe,
    (
        bp_handle* probe_handle,
        host_stats_t* host,
        int packet_size,
        rtt_law_t* rtt_law,
        int index
    ));        

#endif /* end of file */
