#ifndef _gps_socket_data_h_
#define _gps_socket_data_h_
/*   @(#)   gps_socket_data.h   1.21   01/15/04   */

#define MAXCHANNELS_FOR_SOCKETS_TYPE1 12
/* 12 channels max + 4 for geo satellite tracking */
#define MAXCHANNELS_FOR_SOCKETS_TYPE2 16
#include "gpsudp.h"

/* input is L1 P1 L2 P2 and the ref_range which is CA(L1)
 *  for the L2_block, range_2 = P2 - ref_range
 *                    phase_2 = L2 - ref_range + 4.09145556*range_2
 *  for the L1_block, range_1 = P1 - ref_range
 *                    phase_1 = L1 - ref_range + 3.09145556*range_2
 */


typedef struct RANGE_DATA_C { /* 6 bytes */
   char range_phase[5];
   /* first 2 bytes and 2 bits is for the range, next 6 bits and 2 bytes are
    * for phase.
    *
    * range units are in millimeters, from -131071 to 131071   (2^17 - 1)
    * 0000 0000 0000 0000 01 would be +1 mm 
    * 1000 0000 0000 0000 01 would be -1 mm
    * 0100 0000 0000 0000 00 would be  65536 mm
    * 1100 0000 0000 0000 00 would be -65536 mm
    * 0111 1111 1111 1111 11 would be  131071 mm
    * 1111 1111 1111 1111 11 woule be -131071 mm
    * dynamic range must be <= 131.071 meters
    *
    * phase units are in 2/100 millimeters from -4194304 to 4194304
    * 00 0000 0000 0000 0000 0001  would be +.02 mm 
    * 10 0000 0000 0000 0000 0001  would be -.02 mm
    * 01 1111 1111 1111 1111 1111  ( 2097151) would be  41943.02 mm
    * 11 1111 1111 1111 1111 1111  (-2097151) would be -41943.02 mm
    *                              (2^21 - 1)*2 mm
    * dynamic range must be <= 41.94302 meters
    *
    * note if the limits are exceded, a -0 (minus zero) is returned 
    * indicating not a number 
    * 
    * Note however, we extended this dynamic range to 83.88606 meters as
    * below with the spare bits in the ca_range field. If this limit
    * is exceeded we return a -0 ( minus zero )
    */
   unsigned char snr;  /* snr for this data type */
} RANGE_DATA_C;    

typedef struct RANGE_DATA_C_full { /* 17 bytes */
   double range;       /* range in meters */
   double phase;       /* phase in wavelengths */
   unsigned char snr;  /* snr for this data type */
} RANGE_DATA_C_full;    

typedef struct MEAS_DAT_C { /* 21 bytes */
   unsigned char prn;             /* satellite ID */
   unsigned short epoch_sequence; /* like Ashtech seq number of phase epochs */
                                  /* was like this, now modulo 10 hours,     */
                                  /* each digit is now 1 sec, not .05 secs   */
                                  /* like before                             */
   char ca_range[5];              /* ca range in millimeters 
                                   * first 4 bits are status bits, as follows
                                   * if bit 7 on, sucessful packing of ca_range
                                   * if bit 6 on, Z track mode or AS is on
                                   * if bit 5 on, overflow of L2_block phase
                                   * if bit 4 on, overflow of L1_block phase
                                   * next 36 bits are the observable
                                   * 68719.476735 is the max allowable obsev.
                                   * if not packed, L2_block and L1_block is
                                   * just then packed with 0s  
                                   */
   unsigned char snr;             /* receiver snr for ca */
   RANGE_DATA_C  L2_block;
   RANGE_DATA_C  L1_block;
} MEAS_DAT_C;

/* if the dynamic range of the phase in the L2_block/L1_block 
 * is bigger than 41.94302 m, bit 5/4 on indicates that we add an additional
 * 41.94304 m to these numbers
 */

typedef struct MEAS_DAT_C_full { /* 46 bytes */
   unsigned char prn;             /* satellite ID */
   unsigned short epoch_sequence; /* Ashtech seq number of phase epochs */
   double ca_range;               /* ca range in meters */
   unsigned char snr;             /* receiver snr for ca */
   RANGE_DATA_C_full  L1_block;
   RANGE_DATA_C_full  L2_block;
} MEAS_DAT_C_full;

typedef struct MandT { /* 261 bytes */
   unsigned int    gps_minutes;    /* minutes past 6-JAN-1980 00:00:00.0000 */
   unsigned short  gps_millisecs;  /* millisecs to add to the above time    */
   short           navt;           /* S/A clock solution 10*meters.         */
                                   /* clock solution must be within 327 km  */
   unsigned char   Sats_and_Status;/* number of measurements and status.    */
                                   /* first 4 bits (7654) is number less 1: */
                                   /* ie if 0,than 1 sat,if 15 then 16 sats */
                                   /* bits 3,2,1, are for receiver type     */
                                   /* xxxx100x then AZ12 receiver            */
                                   /* xxxx101x then G12  receiver            */
                                   /* xxxx110x then nct  receiver            */
                                   /* xxxx010x then turbo-rogue receiver     */
                                   /* xxxx011x then Benchmark ACT receiver   */
                                   /* xxxx001x then trimble receiver         */
                                   /* bit 0 if on then this is a primary    */
                                   /* stream, wrt_eph to datd_inet          */
                                   /* bit 0 if off then this is a secondary */
                                   /* stream, datd_inet to datd_inet        */
   MEAS_DAT_C      mben[MAXCHANNELS_FOR_SOCKETS_TYPE1];
} MandT;

typedef struct MandT_full { /* 745 bytes */
   unsigned int    gps_minutes;    /* minutes past 6-JAN-1980 00:00:00.0000 */
   unsigned short  gps_millisecs;  /* millisecs to add to the above time    */
   short           navt;           /* S/A clock solution 10*meters.         */
                                   /* clock solution must be within 327 km  */
   unsigned char   Sats_and_Status;/* number of measurements and status.    */
                                   /* first 4 bits is the number less 1:    */
                                   /* ie if 0,than 1 sat,if 15 then 16 sats */
                                   /* last 4 bits is status TBD             */
   MEAS_DAT_C_full mben[MAXCHANNELS_FOR_SOCKETS_TYPE2];
} MandT_full;

typedef struct Sonly {
    EPHEMERIS_DATA_T snav;   /* defined in gpsudp.h -136 bytes- */
} Sonly;

#define MAX_REQUEST 3 /* max number request from datd_inet for re-transmit    */
#define MAX_RESETS 10 /* max times to wait until a new request from datd_inet */
#define MAXSOCBUF 10  /* max size of number udp packets to store in wrt_eph   */

typedef struct Request_Seq {
   unsigned short num_request;
   unsigned short seqnum_request[MAX_REQUEST];
} Request_Seq;

/* type 0, if to request re-transmit, sid is 0 */
/* type 0, if to request re-route, sid is SITEIDREROUTE */
/* type 4, sid is 0 */
/* type 5, sid is 0 */
/* type 6, sid is 0 */

typedef union MandT_Sonly_union {
   Request_Seq data_sequence;    /* type 0 */
   MandT       gps_data;         /* type 1 */
   MandT_full  gps_data_full;    /* type 2 */
   Sonly       eph_data;         /* type 3 */
} MandT_Sonly_union;

#define SIZEOFTYPE0 16          /* re-request for data, header + 8 bytes   */
                                /* if sid is 99 or 100, this is reroute    */
                                /* otherwise, header + num_req, + upto     */
                                /* three seq. numbers                      */
#define SIZEOFTYPE1 269         /* soc data, for 12 prns                   */
#define SIZEOFTYPE2 753         /* unpacked soc data, for 16 prns          */
#define SIZEOFTYPE3 144         /* 136 byte ephemeris data  + header       */

#define SIZEOFTYPE4 16          /* includes header and the utc timetag     */
                                /* heartbeat to twin, header and timetag   */

#define SIZEOFTYPE5 26          /* includes header, sid of 0      8 bytes  */
                                /*          sin_addr of host      4 bytes  */
                                /*          sin_addr of alt_host  4 bytes  */
                                /*          portnumber            2 bytes  */
                                /*          utc timetag           8 bytes  */

#define SIZEOFTYPE6 16          /* heartbeat to bctwin, header and timetag */

#define SITEIDREROUTE 99         

#define MACSIZE 20

/* type 0  is 16 bytes                                                   */
/* type 1  is upto 269 bytes max, 17 + 21*12 at most                     */
/* type 11 is type1 followed by a 20 byte mac, using 8 byte session key  */
/* type 2  is upto 753 bytes max, 17 + 46*12 likely however              */
/*         only type 2 is used for NCT data from wrt_eph to datd_inet    */
/*         and when done so, must be edited by datd_inet on phase        */
/* type 3  is 144 bytes                                                  */
/* type 13 is type3 followed by a 20 byte mac, using 8 byte session key  */
/* type 4  is 16 bytes, heart beat from main to twin     */ 
/* type 5  is 26 bytes, benefactor information           */ 
/* type 6  is 16 bytes, heart beat from main to bctwin   */ 
/* type 7  is  X bytes, as yet undefined, integrity data */
/* type 17 is type7 followed by a 20 byte mac, using 8 byte session key  */
/* type 8  is  X bytes, as yet undefined, integrity data */
/* type 18 is type8 followed by a 20 byte mac, using 8 byte session key  */
/* type 9  is  X bytes, as yet undefined, integrity data */
/* type 19 is type9 followed by a 20 byte mac, using 8 byte session key  */
/* type 101 is remote handshake to datd_inet to generate session key     */
/* size is yet unknown                                                   */
/* type 102 is encrypted session key to remote sites                     */
/* size is 256 + 256 for signature, payload is 8 byte session key        */
/* type 103 is replay of unencrypted session keys to twin of datd_inet   */
/* size is 4 for IP address, plus 8 for session key                      */

/* data types 1, 2, 3, 7, 8, 9 get passed on as "data"                   */

typedef struct gps_socket_data { 
   unsigned short type;          
   unsigned short length;        
   unsigned short seqnum;        /* just a seqnum running from 0 to 43199 */
   unsigned short SiteId;        /* must be uniq for 1 and 3 types        */ 
   MandT_Sonly_union pak;        /* server_inet_TCP.h: MAX_SEQUENCE_NUM 43200 */
} gps_socket_data;
   
/* note that if I do not return SNRs the type1 size can be reduced to 233 */

#endif /* _gps_socket_data_h_ */