1 /*
2  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above
10  *       copyright notice, this list of conditions and the following
11  *       disclaimer in the documentation and/or other materials provided
12  *       with the distribution.
13  *     * Neither the name of The Linux Foundation nor the names of its
14  *       contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #define LOG_TAG "LocSvc_MeasurementCorrectionsInterface"
31 
32 #include <log_util.h>
33 #include "MeasurementCorrections.h"
34 
35 namespace android {
36 namespace hardware {
37 namespace gnss {
38 namespace measurement_corrections {
39 namespace V1_1 {
40 namespace implementation {
41 
42 using ::android::hardware::hidl_array;
43 using ::android::hardware::hidl_memory;
44 using ::android::hardware::hidl_string;
45 using ::android::hardware::hidl_vec;
46 using ::android::hardware::Return;
47 using ::android::hardware::Void;
48 using ::android::sp;
49 using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
50 using ::android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
51 using MeasurementCorrectionsV1_0 =
52         ::android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
53 using MeasurementCorrectionsV1_1 =
54         ::android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
55 
56 static MeasurementCorrections* spMeasurementCorrections = nullptr;
57 
serviceDied(uint64_t cookie,const wp<IBase> & who)58 void MeasurementCorrections::GnssMeasurementCorrectionsDeathRecipient::serviceDied(uint64_t cookie,
59         const wp<IBase>& who) {
60     LOC_LOGe("service died. cookie: %llu, who: %p", static_cast<unsigned long long>(cookie), &who);
61     // Gnss::GnssDeathrecipient will stop the session
62     // we inform the adapter that service has died
63     if (nullptr == spMeasurementCorrections) {
64         LOC_LOGe("spMeasurementCorrections is nullptr");
65         return;
66     }
67     if (nullptr == spMeasurementCorrections->mGnss ||
68         nullptr == spMeasurementCorrections->mGnss->getGnssInterface()) {
69         LOC_LOGe("Null GNSS interface");
70         return;
71     }
72     spMeasurementCorrections->mGnss->getGnssInterface()->measCorrClose();
73 }
74 
MeasurementCorrections(Gnss * gnss)75 MeasurementCorrections::MeasurementCorrections(Gnss* gnss) : mGnss(gnss) {
76     mGnssMeasurementCorrectionsDeathRecipient = new GnssMeasurementCorrectionsDeathRecipient(this);
77     spMeasurementCorrections = this;
78 }
79 
~MeasurementCorrections()80 MeasurementCorrections::~MeasurementCorrections() {
81     spMeasurementCorrections = nullptr;
82 }
83 
measCorrSetCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities)84 void MeasurementCorrections::measCorrSetCapabilitiesCb(
85         GnssMeasurementCorrectionsCapabilitiesMask capabilities) {
86     if (nullptr != spMeasurementCorrections) {
87         spMeasurementCorrections->setCapabilitiesCb(capabilities);
88     }
89 }
90 
setCapabilitiesCb(GnssMeasurementCorrectionsCapabilitiesMask capabilities)91 void MeasurementCorrections::setCapabilitiesCb(
92     GnssMeasurementCorrectionsCapabilitiesMask capabilities) {
93 
94     if (mMeasurementCorrectionsCbIface != nullptr) {
95         uint32_t measCorrCapabilities = 0;
96 
97         // Convert from one enum to another
98         if (capabilities & GNSS_MEAS_CORR_LOS_SATS) {
99             measCorrCapabilities |=
100                     IMeasurementCorrectionsCallback::Capabilities::LOS_SATS;
101         }
102         if (capabilities & GNSS_MEAS_CORR_EXCESS_PATH_LENGTH) {
103             measCorrCapabilities |=
104                     IMeasurementCorrectionsCallback::Capabilities::EXCESS_PATH_LENGTH;
105         }
106         if (capabilities & GNSS_MEAS_CORR_REFLECTING_PLANE) {
107             measCorrCapabilities |=
108                     IMeasurementCorrectionsCallback::Capabilities::REFLECTING_PLANE;
109         }
110 
111         auto r = mMeasurementCorrectionsCbIface->setCapabilitiesCb(measCorrCapabilities);
112         if (!r.isOk()) {
113             LOC_LOGw("Error invoking setCapabilitiesCb %s", r.description().c_str());
114         }
115     } else {
116         LOC_LOGw("setCallback has not been called yet");
117     }
118 }
119 
setCorrections(const MeasurementCorrectionsV1_0 & corrections)120 Return<bool> MeasurementCorrections::setCorrections(
121         const MeasurementCorrectionsV1_0& corrections) {
122 
123     GnssMeasurementCorrections gnssMeasurementCorrections = {};
124 
125     V2_1::implementation::convertMeasurementCorrections(corrections, gnssMeasurementCorrections);
126 
127     return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
128 }
129 
setCorrections_1_1(const MeasurementCorrectionsV1_1 & corrections)130 Return<bool> MeasurementCorrections::setCorrections_1_1(
131         const MeasurementCorrectionsV1_1& corrections) {
132 
133     GnssMeasurementCorrections gnssMeasurementCorrections = {};
134 
135     V2_1::implementation::convertMeasurementCorrections(
136             corrections.v1_0, gnssMeasurementCorrections);
137 
138     gnssMeasurementCorrections.hasEnvironmentBearing = corrections.hasEnvironmentBearing;
139     gnssMeasurementCorrections.environmentBearingDegrees =
140             corrections.environmentBearingDegrees;
141     gnssMeasurementCorrections.environmentBearingUncertaintyDegrees =
142             corrections.environmentBearingUncertaintyDegrees;
143 
144     for (int i = 0; i < corrections.satCorrections.size(); i++) {
145         GnssSingleSatCorrection gnssSingleSatCorrection = {};
146 
147         V2_1::implementation::convertSingleSatCorrections(
148                 corrections.satCorrections[i].v1_0, gnssSingleSatCorrection);
149         switch (corrections.satCorrections[i].constellation) {
150         case (::android::hardware::gnss::V2_0::GnssConstellationType::GPS):
151             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GPS;
152             break;
153         case (::android::hardware::gnss::V2_0::GnssConstellationType::SBAS):
154             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_SBAS;
155             break;
156         case (::android::hardware::gnss::V2_0::GnssConstellationType::GLONASS):
157             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GLONASS;
158             break;
159         case (::android::hardware::gnss::V2_0::GnssConstellationType::QZSS):
160             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_QZSS;
161             break;
162         case (::android::hardware::gnss::V2_0::GnssConstellationType::BEIDOU):
163             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_BEIDOU;
164             break;
165         case (::android::hardware::gnss::V2_0::GnssConstellationType::GALILEO):
166             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GALILEO;
167             break;
168         case (::android::hardware::gnss::V2_0::GnssConstellationType::IRNSS):
169             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_NAVIC;
170             break;
171         case (::android::hardware::gnss::V2_0::GnssConstellationType::UNKNOWN):
172         default:
173             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_UNKNOWN;
174             break;
175         }
176         gnssMeasurementCorrections.satCorrections.push_back(gnssSingleSatCorrection);
177     }
178 
179     return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
180 }
181 
setCallback(const sp<V1_0::IMeasurementCorrectionsCallback> & callback)182 Return<bool> MeasurementCorrections::setCallback(
183         const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
184 
185     if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
186         LOC_LOGe("Null GNSS interface");
187         return false;
188     }
189     mMeasurementCorrectionsCbIface = callback;
190 
191     return mGnss->getGnssInterface()->measCorrInit(measCorrSetCapabilitiesCb);
192 }
193 
194 }  // namespace implementation
195 }  // namespace V1_1
196 }  // namespace measurement_corrections
197 }  // namespace gnss
198 }  // namespace hardware
199 }  // namespace android
200