public IGPSSatelliteVehicle[] GetSatelliteData() { GPSSatDataType[] iQueSatData = new GPSSatDataType[maxSatellites]; ushort err = GPSGetSatellites(iQueSatData); if (err == 0) { // Work out how many satellites are in view. int numSatellitesInView = 0; for (int i = 0; i < maxSatellites; i++) { if (iQueSatData[i].svid != 255) { numSatellitesInView++; } } // Construct the satellite data class. IGPSSatelliteVehicle[] satelliteVehicles = new IGPSSatelliteVehicle[numSatellitesInView]; int index = 0; for (int i = 0; i < maxSatellites; i++) { if (iQueSatData[i].svid != 255) { GPSSatelliteVehicle vehicle = new GPSSatelliteVehicle(); vehicle.PRN = iQueSatData[i].svid; vehicle.AziumthDegrees = (int)Math.Round(iQueSatData[i].azimuth * 180 / Math.PI); vehicle.ElevationDegrees = (int)Math.Round(iQueSatData[i].elevation * 180 / Math.PI); vehicle.SNRdB = iQueSatData[i].snr / 100; vehicle.HaveEphemerisData = (iQueSatData[i].status & gpsSatEphMask) > 0; vehicle.HaveDifferentialCorrection = (iQueSatData[i].status & gpsSatDifMask) > 0; vehicle.UsedInFix = (iQueSatData[i].status & gpsSatUsedMask) > 0; vehicle.IsRising = (iQueSatData[i].status & gpsSatRisingMask) > 0; satelliteVehicles[index++] = vehicle; } } // Return the result. return(satelliteVehicles); } else { return(null); } }
private void ProcessGSV(string[] parts) { // Check that we have the correct number of parts. int numMessages, messageNumber, numSatellitesInView, numSatellitesInSentence; if (parts.Length < 4) { CallOnLogEvent("Invalid GSV sentence."); return; } try { numMessages = int.Parse(parts[1]); messageNumber = int.Parse(parts[2]); numSatellitesInView = int.Parse(parts[3]); numSatellitesInSentence = messageNumber < numMessages ? 4 : numSatellitesInView - 4 * (numMessages - 1); } catch { CallOnLogEvent("Invalid GSV sentence."); return; } // Need to allow for cases where the exact number of satellites are present, // and where placeholder commas are used to pad missing satellite data in the // last sentence. if ((parts.Length != numSatellitesInSentence * 4 + 4) && (parts.Length != 20)) { CallOnLogEvent("Invalid GSV sentence."); return; } // Create a new satellite data instance if this is the first record. if (messageNumber == 1) { partialSatelliteVehicles = new GPSSatelliteVehicle[numSatellitesInView]; partialSatelliteVehicleIndex = 0; } // Check that the message isn't out of sequence. if (messageNumber != lastGSVMessageNumber + 1) { partialSatelliteVehicles = null; partialSatelliteVehicleIndex = 0; } if (messageNumber == numMessages) { lastGSVMessageNumber = 0; } else { lastGSVMessageNumber = messageNumber; } // Sanity check. if ((partialSatelliteVehicles != null) && (numSatellitesInView != partialSatelliteVehicles.Length)) { partialSatelliteVehicles = null; partialSatelliteVehicleIndex = 0; } // Check if we have a satellite data instance in case we didn't see the // first record or we invalidated the satellite data above. if (partialSatelliteVehicles != null) { // Add the satellite data to the list, if there is space. for (int i = 0; i < numSatellitesInSentence; i++) { // Sanity check. if (partialSatelliteVehicleIndex >= numSatellitesInView) { throw new Exception("Too many satellite vehicles in GSV sentence."); } // Create a new vehicle entry. GPSSatelliteVehicle vehicle = new GPSSatelliteVehicle(); partialSatelliteVehicles[partialSatelliteVehicleIndex++] = vehicle; // Populate the entry. try { int partOffset = i * 4 + 4; vehicle.PRN = int.Parse(parts[partOffset]); vehicle.ElevationDegrees = parts[partOffset + 1].Equals(String.Empty) ? 0 : int.Parse(parts[partOffset + 1]); vehicle.AziumthDegrees = parts[partOffset + 2].Equals(String.Empty) ? 0 : int.Parse(parts[partOffset + 2]); vehicle.SNRdB = parts[partOffset + 3].Equals(String.Empty) ? 0 : int.Parse(parts[partOffset + 3]); vehicle.HaveEphemerisData = true; // Assumed. } catch { throw new Exception("Invalid satellite vehicle data in GSV sentence."); } } // If this is the last message then publish the data. if (messageNumber == numMessages) { // Flag which satellites are used in the fix if this information is // available. if ((gsaData != null) && (DateTime.Now.Subtract(gsaData.timeReceived).TotalSeconds < gsaDataValiditySeconds)) { for (int i = 0; i < gsaData.satellitesInFix.Length; i++) { for (int j = 0; j < partialSatelliteVehicleIndex; j++) { if (gsaData.satellitesInFix[i] == partialSatelliteVehicles[j].PRN) { partialSatelliteVehicles[j].UsedInFix = true; break; } } } } // Sort the vehicles in order of PRN. Array.Sort(partialSatelliteVehicles); // Publish the data. m_MostRecentSatelliteVehicles = partialSatelliteVehicles; // Tidy up. partialSatelliteVehicles = null; partialSatelliteVehicleIndex = 0; } } }