/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.gnss.measurement_corrections@1.0;

import android.hardware.gnss@1.0::GnssConstellationType;

/**
 * A struct with measurement corrections for a single visible satellites
 *
 * The bit mask singleSatCorrectionFlags indicates which correction values are valid in the struct
 */
struct SingleSatCorrection {

    /** Contains GnssSingleSatCorrectionFlags bits. */
    bitfield<GnssSingleSatCorrectionFlags> singleSatCorrectionFlags;

    /**
     * Defines the constellation of the given satellite.
     */
    GnssConstellationType constellation;

    /**
     * Satellite vehicle ID number, as defined in GnssSvInfo::svid
     */
    uint16_t svid;

    /**
     * Carrier frequency of the signal to be corrected, for example it can be the
     * GPS center frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc.
     *
     * For a receiver with capabilities to track multiple frequencies for the same satellite,
     * multiple corrections for the same satellite may be provided.
     */
    float carrierFrequencyHz;

    /**
     * The probability that the satellite is estimated to be in Line-of-Sight condition at the given
     * location.
     */
    float probSatIsLos;

    /**
     * Excess path length to be subtracted from pseudorange before using it in calculating location.
     *
     * Note this value is NOT to be used to adjust the GnssMeasurementCallback outputs.
     */
    float excessPathLengthMeters;

    /** Error estimate (1-sigma) for the Excess path length estimate */
    float excessPathLengthUncertaintyMeters;

    /**
     * Defines the reflecting plane characteristics such as location and azimuth
     *
     * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
     * means either reflection planes serving is not supported or the satellite signal has gone
     * through multiple reflections.
     */
     ReflectingPlane reflectingPlane;
};

/**
 * A struct containing a set of measurement corrections for all used GNSS satellites at the location
 * specified by latitudeDegrees, longitudeDegrees, altitudeMeters and at the time of week specified
 * toaGpsNanosecondsOfWeek
 */
struct MeasurementCorrections {
    /** Represents latitude in degrees at which the corrections are computed.. */
    double latitudeDegrees;

    /** Represents longitude in degrees at which the corrections are computed.. */
    double longitudeDegrees;

    /**
     * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections
     * are computed.
     */
    double altitudeMeters;

    /**
     * Represents the horizontal uncertainty (63% to 68% confidence) in meters on the device
     * position at which the corrections are provided.
     *
     * This value is useful for example to judge how accurate the provided corrections are.
     */
    double horizontalPositionUncertaintyMeters;

    /**
     * Represents the vertical uncertainty (63% to 68% confidence) in meters on the device position
     * at which the corrections are provided.
     *
     * This value is useful for example to judge how accurate the provided corrections are.
     */
    double verticalPositionUncertaintyMeters;

    /** Time Of Applicability, GPS time of week in nanoseconds. */
    uint64_t toaGpsNanosecondsOfWeek;

    /**
     * A set of SingleSatCorrection each containing measurement corrections for a satellite in view
     */
    vec<SingleSatCorrection> satCorrections;
};

/**
 * A struct containing the characteristics of the reflecting plane that the satellite signal has
 * bounced from.
 *
 * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
 * means either reflection planes serving is not supported or the satellite signal has gone
 * through multiple reflections.
 */
struct ReflectingPlane {
    /** Represents latitude of the reflecting plane in degrees. */
    double latitudeDegrees;

    /** Represents longitude of the reflecting plane in degrees. */
    double longitudeDegrees;

    /**
     * Represents altitude of the reflecting point in the plane in meters above the WGS 84 reference
     * ellipsoid.
     */
    double altitudeMeters;

    /** Represents azimuth clockwise from north of the reflecting plane in degrees. */
    double azimuthDegrees;
};

/** Bit mask to indicate which values are valid in a SingleSatCorrection object. */
enum GnssSingleSatCorrectionFlags : uint16_t {
    /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */
    HAS_SAT_IS_LOS_PROBABILITY               = 0x0001,
    /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */
    HAS_EXCESS_PATH_LENGTH                   = 0x0002,
    /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */
    HAS_EXCESS_PATH_LENGTH_UNC               = 0x0004,
    /** GnssSingleSatCorrectionFlags has valid Reflecting Plane field. */
    HAS_REFLECTING_PLANE                     = 0x0008
};