public static string FixDimensionString(FixDimension value)
        {
            switch (value)
            {
            case FixDimension.None:
                return("None");

            case FixDimension.Clock_1D:
                return("1D Clock");

            case FixDimension.Position_2D:
                return("2D Position");

            case FixDimension.Position_3D:
                return("3D Position");

            case FixDimension.OverDetermined:
                return("OverDet Clock");

            default:
                return("Unknown");
            }
        }
        /// <summary>
        /// This packet provides a list of satellites used for position or time-only fixes by the GPS
        /// receiver. The packet also provides the dilution of precision values PDOP, HDOP, VDOP and TDOP 
        /// of that set and provides the current mode (automatic or manual, 3-D or 2-D, Over-Determined Clock
        /// mode, etc.). This packet has variable length equal to (17 + nsvs) where "nsvs" is the
        /// number of satellites used in the solution. If an SV is rejected for use by the T-RAIM
        /// algorithm then the SV PRN value will be negative.
        /// 
        /// PDOP = positional DOP
        /// HDOP = horizontal DOP
        /// VDOP = vertical DOP
        /// TDOP = temporal DOP
        /// 
        /// Note: The GPS receiver sends this packet in response to packet 0x24 or automatically. 
        /// </summary>
        private void sat_list(TsipPacket tp)
        {
            byte mode, count, dimension;

            dimension = mode = count = tp.GetNextByte();
            dimension &= 0x07;  // fix dimension is in first 3 bits
            mode &= 0x08;       // mode is in bit 3
            mode >>= 3;
            count >>= 4;        // tracked sat count in upper 4 bits

            //Debug.Print(":0x6D    (Satellite List count = {0})", count);

            positional_dop = Helpers.FloatToFixPrecision(tp.GetNextSingle());
            horizontal_dop = Helpers.FloatToFixPrecision(tp.GetNextSingle());
            vertical_dop = Helpers.FloatToFixPrecision(tp.GetNextSingle());
            temporal_dop = Helpers.FloatToFixPrecision(tp.GetNextSingle());
            fix_dimension = Helpers.ByteToFixDimension(dimension);
            fix_mode = Helpers.ByteToFixMode(mode);

            for (int i = 0; i < 32; i++)    // clear current tracking flags
                Satellites[i].UsedInFix = false;

            for (int i = 0; i < count; i++)
            {
                bool used = true;
                byte prn = tp.GetNextByte();
                if ((prn & 0x80) == 0x80)   // satellite is tracked but is not used in fix
                {
                    used = false;
                    prn &= 0x7F;
                }
                prn--;
                if (prn > 31)
                    continue;               // disregard bogus data

                Satellites[prn].Tracked = true;
                Satellites[prn].UsedInFix = used;
            }
        }