1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <chrono>
18 #include "gnss_measurement.h"
19 #include "util.h"
20 
21 namespace goldfish {
22 using ::android::hardware::hidl_vec;
23 
~GnssMeasurement20()24 GnssMeasurement20::~GnssMeasurement20() {
25     if (m_isRunning) {
26         stopLocked();
27     }
28 }
29 
30 Return<GnssMeasurementStatus10>
setCallback_2_0(const sp<ahg20::IGnssMeasurementCallback> & callback,bool enableFullTracking)31 GnssMeasurement20::setCallback_2_0(const sp<ahg20::IGnssMeasurementCallback>& callback,
32                                    bool enableFullTracking) {
33     (void)enableFullTracking;
34     if (callback == nullptr) {
35         return GnssMeasurementStatus10::ERROR_GENERIC;
36     }
37 
38     std::unique_lock<std::mutex> lock(m_mtx);
39     if (m_isRunning) {
40         stopLocked();
41     }
42 
43     m_callback = callback;
44     startLocked();
45 
46     return GnssMeasurementStatus10::SUCCESS;
47 }
48 
close()49 Return<void> GnssMeasurement20::close() {
50     std::unique_lock<std::mutex> lock(m_mtx);
51     if (m_isRunning) {
52         stopLocked();
53     }
54 
55     m_callback = nullptr;
56     return {};
57 }
58 
startLocked()59 void GnssMeasurement20::startLocked() {
60     m_thread = std::thread([this](){
61         while (m_isRunning) {
62             update();
63             std::this_thread::sleep_for(std::chrono::milliseconds(1000));
64         }
65     });
66     m_isRunning = true;
67 }
68 
stopLocked()69 void GnssMeasurement20::stopLocked() {
70     m_isRunning = false;
71     m_thread.join();
72 }
73 
update()74 void GnssMeasurement20::update() {
75     using GnssMeasurement20 = ahg20::IGnssMeasurementCallback::GnssMeasurement;
76     using GnssAccumulatedDeltaRangeState10 = ahg10::IGnssMeasurementCallback::GnssAccumulatedDeltaRangeState;
77     using GnssMeasurementFlags10 = ahg10::IGnssMeasurementCallback::GnssMeasurementFlags;
78     using GnssMultipathIndicator10 = ahg10::IGnssMeasurementCallback::GnssMultipathIndicator;
79     using GnssMeasurementState20 = ahg20::IGnssMeasurementCallback::GnssMeasurementState;
80     using GnssData = ahg20::IGnssMeasurementCallback::GnssData;
81 
82     ahg10::IGnssMeasurementCallback::GnssMeasurement measurement10 = {
83         .flags = GnssMeasurementFlags10::HAS_CARRIER_FREQUENCY | 0,
84         .svid = 6,
85         .constellation = ahg10::GnssConstellationType::GPS,
86         .timeOffsetNs = 0.0,
87         .receivedSvTimeInNs = 8195997131077,
88         .receivedSvTimeUncertaintyInNs = 15,
89         .cN0DbHz = 30.0,
90         .pseudorangeRateMps = -484.13739013671875,
91         .pseudorangeRateUncertaintyMps = 0.12,
92         .accumulatedDeltaRangeState = GnssAccumulatedDeltaRangeState10::ADR_STATE_UNKNOWN | 0,
93         .accumulatedDeltaRangeM = 0.0,
94         .accumulatedDeltaRangeUncertaintyM = 0.0,
95         .carrierFrequencyHz = 1.59975e+09,
96         .multipathIndicator = GnssMultipathIndicator10::INDICATOR_UNKNOWN
97     };
98     ahg11::IGnssMeasurementCallback::GnssMeasurement measurement11 = {
99         .v1_0 = measurement10,
100         .accumulatedDeltaRangeState = 0
101     };
102 
103     ahg20::IGnssMeasurementCallback::GnssMeasurement measurement20 = {
104         .v1_1 = measurement11,
105         .codeType = "C",
106         .state = GnssMeasurementState20::STATE_CODE_LOCK |
107                  GnssMeasurementState20::STATE_BIT_SYNC |
108                  GnssMeasurementState20::STATE_SUBFRAME_SYNC |
109                  GnssMeasurementState20::STATE_TOW_DECODED |
110                  GnssMeasurementState20::STATE_GLO_STRING_SYNC |
111                  GnssMeasurementState20::STATE_GLO_TOD_DECODED,
112         .constellation = ahg20::GnssConstellationType::GPS,
113     };
114 
115     hidl_vec<GnssMeasurement20> measurements(1);
116     measurements[0] = measurement20;
117 
118     const int64_t nowNs = util::nowNanos();
119     const int64_t fullBiasNs = (nowNs % 15331) * ((nowNs & 1) ? -1 : 1);
120     const int64_t hwTimeNs = nowNs + fullBiasNs; // local hardware clock
121 
122     ahg10::IGnssMeasurementCallback::GnssClock clock10 = {
123         .gnssClockFlags = 0,
124         .leapSecond = 0,
125         .timeNs = hwTimeNs,
126         .timeUncertaintyNs = 4.5,
127         .fullBiasNs = fullBiasNs,
128         .biasNs = 1.5,
129         .biasUncertaintyNs = .7,
130         .driftNsps = -51.757811607455452,
131         .driftUncertaintyNsps = 310.64968328491528,
132         .hwClockDiscontinuityCount = 1
133     };
134 
135     GnssData gnssData = {
136         .measurements = measurements,
137         .clock = clock10,
138         .elapsedRealtime = util::makeElapsedRealtime(util::nowNanos())
139     };
140 
141     std::unique_lock<std::mutex> lock(m_mtx);
142     m_callback->gnssMeasurementCb_2_0(gnssData);
143 }
144 
145 /// old and deprecated /////////////////////////////////////////////////////////
setCallback_1_1(const sp<ahg11::IGnssMeasurementCallback> &,bool)146 Return<GnssMeasurementStatus10> GnssMeasurement20::setCallback_1_1(const sp<ahg11::IGnssMeasurementCallback>&, bool) {
147     return GnssMeasurementStatus10::ERROR_GENERIC;
148 }
149 
setCallback(const sp<ahg10::IGnssMeasurementCallback> &)150 Return<GnssMeasurementStatus10> GnssMeasurement20::setCallback(const sp<ahg10::IGnssMeasurementCallback>&) {
151     return GnssMeasurementStatus10::ERROR_GENERIC;
152 }
153 
154 
155 }  // namespace goldfish
156