blob: 1f95ff95dca71ff9dfcb6aa834119abd7a92b793 [file] [log] [blame]
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -08001/*
2 * Copyright (C) 2018 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 */
Yu-Han Yang030d0332018-12-09 10:47:42 -080016#define LOG_TAG "GnssMeasurement"
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080017
18#include "GnssMeasurement.h"
Pierre Fite-Georgel12ac2b52019-01-17 16:56:17 -080019
Yu-Han Yang030d0332018-12-09 10:47:42 -080020#include <log/log.h>
Pierre Fite-Georgel12ac2b52019-01-17 16:56:17 -080021#include <utils/SystemClock.h>
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080022
23namespace android {
24namespace hardware {
25namespace gnss {
26namespace V2_0 {
27namespace implementation {
28
Yu-Han Yang6999a0f2019-03-14 11:08:43 -070029using GnssConstellationType = V2_0::GnssConstellationType;
Yu-Han Yang030d0332018-12-09 10:47:42 -080030using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
Yu-Han Yang031738b2019-02-01 19:58:04 -080031using GnssMeasurementState = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
Yu-Han Yang030d0332018-12-09 10:47:42 -080032
33sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr;
34
35GnssMeasurement::GnssMeasurement() : mMinIntervalMillis(1000) {}
36
37GnssMeasurement::~GnssMeasurement() {
38 stop();
39}
40
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080041// Methods from V1_0::IGnssMeasurement follow.
42Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback(
43 const sp<V1_0::IGnssMeasurementCallback>&) {
44 // TODO implement
45 return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
46}
47
48Return<void> GnssMeasurement::close() {
Yu-Han Yang6999a0f2019-03-14 11:08:43 -070049 ALOGD("close");
Yu-Han Yang030d0332018-12-09 10:47:42 -080050 std::unique_lock<std::mutex> lock(mMutex);
51 stop();
52 sCallback = nullptr;
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080053 return Void();
54}
55
56// Methods from V1_1::IGnssMeasurement follow.
57Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_1_1(
58 const sp<V1_1::IGnssMeasurementCallback>&, bool) {
59 // TODO implement
60 return V1_0::IGnssMeasurement::GnssMeasurementStatus{};
61}
62
63// Methods from V2_0::IGnssMeasurement follow.
64Return<V1_0::IGnssMeasurement::GnssMeasurementStatus> GnssMeasurement::setCallback_2_0(
Yu-Han Yang030d0332018-12-09 10:47:42 -080065 const sp<V2_0::IGnssMeasurementCallback>& callback, bool) {
Yu-Han Yang6999a0f2019-03-14 11:08:43 -070066 ALOGD("setCallback_2_0");
Yu-Han Yang030d0332018-12-09 10:47:42 -080067 std::unique_lock<std::mutex> lock(mMutex);
68 sCallback = callback;
69
70 if (mIsActive) {
71 ALOGW("GnssMeasurement callback already set. Resetting the callback...");
72 stop();
73 }
74 start();
75
76 return V1_0::IGnssMeasurement::GnssMeasurementStatus::SUCCESS;
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080077}
78
Yu-Han Yang030d0332018-12-09 10:47:42 -080079void GnssMeasurement::start() {
Yu-Han Yang6999a0f2019-03-14 11:08:43 -070080 ALOGD("start");
Yu-Han Yang030d0332018-12-09 10:47:42 -080081 mIsActive = true;
82 mThread = std::thread([this]() {
83 while (mIsActive == true) {
84 auto measurement = this->getMockMeasurement();
85 this->reportMeasurement(measurement);
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -080086
Yu-Han Yang030d0332018-12-09 10:47:42 -080087 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
88 }
89 });
90}
91
92void GnssMeasurement::stop() {
Yu-Han Yang6999a0f2019-03-14 11:08:43 -070093 ALOGD("stop");
Yu-Han Yang030d0332018-12-09 10:47:42 -080094 mIsActive = false;
95 if (mThread.joinable()) {
96 mThread.join();
97 }
98}
99
100GnssData GnssMeasurement::getMockMeasurement() {
101 V1_0::IGnssMeasurementCallback::GnssMeasurement measurement_1_0 = {
Yu-Han Yang6999a0f2019-03-14 11:08:43 -0700102 .flags = (uint32_t)GnssMeasurementFlags::HAS_CARRIER_FREQUENCY,
103 .svid = (int16_t)6,
104 .constellation = V1_0::GnssConstellationType::UNKNOWN,
105 .timeOffsetNs = 0.0,
106 .receivedSvTimeInNs = 8195997131077,
107 .receivedSvTimeUncertaintyInNs = 15,
108 .cN0DbHz = 30.0,
109 .pseudorangeRateMps = -484.13739013671875,
110 .pseudorangeRateUncertaintyMps = 1.0379999876022339,
111 .accumulatedDeltaRangeState = (uint32_t)V1_0::IGnssMeasurementCallback::
112 GnssAccumulatedDeltaRangeState::ADR_STATE_UNKNOWN,
113 .accumulatedDeltaRangeM = 0.0,
114 .accumulatedDeltaRangeUncertaintyM = 0.0,
115 .carrierFrequencyHz = 1.59975e+09,
116 .multipathIndicator =
117 V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
Yu-Han Yang030d0332018-12-09 10:47:42 -0800118 V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
Yu-Han Yang031738b2019-02-01 19:58:04 -0800119 V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
120 .v1_1 = measurement_1_1,
Yu-Han Yang221a85e2019-03-11 19:06:10 -0700121 .codeType = "C",
Yu-Han Yang031738b2019-02-01 19:58:04 -0800122 .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
123 GnssMeasurementState::STATE_SUBFRAME_SYNC |
124 GnssMeasurementState::STATE_TOW_DECODED |
125 GnssMeasurementState::STATE_GLO_STRING_SYNC |
Nick Desaulniers477c7e82019-10-11 13:40:54 -0700126 GnssMeasurementState::STATE_GLO_TOD_DECODED,
127 .constellation = GnssConstellationType::GLONASS,
128 };
Yu-Han Yang030d0332018-12-09 10:47:42 -0800129
130 hidl_vec<IGnssMeasurementCallback::GnssMeasurement> measurements(1);
131 measurements[0] = measurement_2_0;
132 V1_0::IGnssMeasurementCallback::GnssClock clock = {.timeNs = 2713545000000,
133 .fullBiasNs = -1226701900521857520,
134 .biasNs = 0.59689998626708984,
135 .biasUncertaintyNs = 47514.989972114563,
136 .driftNsps = -51.757811607455452,
137 .driftUncertaintyNsps = 310.64968328491528,
138 .hwClockDiscontinuityCount = 1};
Pierre Fite-Georgel12ac2b52019-01-17 16:56:17 -0800139
140 ElapsedRealtime timestamp = {
141 .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
142 ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
143 .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
144 // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
145 // In an actual implementation provide an estimate of the synchronization uncertainty
146 // or don't set the field.
147 .timeUncertaintyNs = 1000000};
148
149 GnssData gnssData = {
150 .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
Yu-Han Yang030d0332018-12-09 10:47:42 -0800151 return gnssData;
152}
153
154void GnssMeasurement::reportMeasurement(const GnssData& data) {
155 ALOGD("reportMeasurement()");
156 std::unique_lock<std::mutex> lock(mMutex);
157 if (sCallback == nullptr) {
158 ALOGE("%s: GnssMeasurement::sCallback is null.", __func__);
159 return;
160 }
161 sCallback->gnssMeasurementCb_2_0(data);
162}
163
Yu-Han Yang9c6c20b2018-11-06 14:12:49 -0800164} // namespace implementation
165} // namespace V2_0
166} // namespace gnss
167} // namespace hardware
168} // namespace android