1 /*
2  * Copyright (c) 2020-2021, 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     std::unique_lock<std::mutex> lock(mMutex);
95     auto measCorrCbIface(mMeasurementCorrectionsCbIface);
96     lock.unlock();
97     if (measCorrCbIface != nullptr) {
98         uint32_t measCorrCapabilities = 0;
99 
100         // Convert from one enum to another
101         if (capabilities & GNSS_MEAS_CORR_LOS_SATS) {
102             measCorrCapabilities |=
103                     IMeasurementCorrectionsCallback::Capabilities::LOS_SATS;
104         }
105         if (capabilities & GNSS_MEAS_CORR_EXCESS_PATH_LENGTH) {
106             measCorrCapabilities |=
107                     IMeasurementCorrectionsCallback::Capabilities::EXCESS_PATH_LENGTH;
108         }
109         if (capabilities & GNSS_MEAS_CORR_REFLECTING_PLANE) {
110             measCorrCapabilities |=
111                     IMeasurementCorrectionsCallback::Capabilities::REFLECTING_PLANE;
112         }
113 
114         auto r = measCorrCbIface->setCapabilitiesCb(measCorrCapabilities);
115         if (!r.isOk()) {
116             LOC_LOGw("Error invoking setCapabilitiesCb %s", r.description().c_str());
117         }
118     } else {
119         LOC_LOGw("setCallback has not been called yet");
120     }
121 }
122 
setCorrections(const MeasurementCorrectionsV1_0 & corrections)123 Return<bool> MeasurementCorrections::setCorrections(
124         const MeasurementCorrectionsV1_0& corrections) {
125 
126     GnssMeasurementCorrections gnssMeasurementCorrections = {};
127 
128     V2_1::implementation::convertMeasurementCorrections(corrections, gnssMeasurementCorrections);
129 
130     return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
131 }
132 
setCorrections_1_1(const MeasurementCorrectionsV1_1 & corrections)133 Return<bool> MeasurementCorrections::setCorrections_1_1(
134         const MeasurementCorrectionsV1_1& corrections) {
135 
136     GnssMeasurementCorrections gnssMeasurementCorrections = {};
137 
138     V2_1::implementation::convertMeasurementCorrections(
139             corrections.v1_0, gnssMeasurementCorrections);
140 
141     gnssMeasurementCorrections.hasEnvironmentBearing = corrections.hasEnvironmentBearing;
142     gnssMeasurementCorrections.environmentBearingDegrees =
143             corrections.environmentBearingDegrees;
144     gnssMeasurementCorrections.environmentBearingUncertaintyDegrees =
145             corrections.environmentBearingUncertaintyDegrees;
146 
147     for (int i = 0; i < corrections.satCorrections.size(); i++) {
148         GnssSingleSatCorrection gnssSingleSatCorrection = {};
149 
150         V2_1::implementation::convertSingleSatCorrections(
151                 corrections.satCorrections[i].v1_0, gnssSingleSatCorrection);
152         switch (corrections.satCorrections[i].constellation) {
153         case (::android::hardware::gnss::V2_0::GnssConstellationType::GPS):
154             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GPS;
155             break;
156         case (::android::hardware::gnss::V2_0::GnssConstellationType::SBAS):
157             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_SBAS;
158             break;
159         case (::android::hardware::gnss::V2_0::GnssConstellationType::GLONASS):
160             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GLONASS;
161             break;
162         case (::android::hardware::gnss::V2_0::GnssConstellationType::QZSS):
163             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_QZSS;
164             break;
165         case (::android::hardware::gnss::V2_0::GnssConstellationType::BEIDOU):
166             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_BEIDOU;
167             break;
168         case (::android::hardware::gnss::V2_0::GnssConstellationType::GALILEO):
169             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_GALILEO;
170             break;
171         case (::android::hardware::gnss::V2_0::GnssConstellationType::IRNSS):
172             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_NAVIC;
173             break;
174         case (::android::hardware::gnss::V2_0::GnssConstellationType::UNKNOWN):
175         default:
176             gnssSingleSatCorrection.svType = GNSS_SV_TYPE_UNKNOWN;
177             break;
178         }
179         gnssMeasurementCorrections.satCorrections.push_back(gnssSingleSatCorrection);
180     }
181 
182     return mGnss->getGnssInterface()->measCorrSetCorrections(gnssMeasurementCorrections);
183 }
184 
setCallback(const sp<V1_0::IMeasurementCorrectionsCallback> & callback)185 Return<bool> MeasurementCorrections::setCallback(
186         const sp<V1_0::IMeasurementCorrectionsCallback>& callback) {
187 
188     if (nullptr == mGnss || nullptr == mGnss->getGnssInterface()) {
189         LOC_LOGe("Null GNSS interface");
190         return false;
191     }
192     std::unique_lock<std::mutex> lock(mMutex);
193     mMeasurementCorrectionsCbIface = callback;
194     lock.unlock();
195 
196     return mGnss->getGnssInterface()->measCorrInit(measCorrSetCapabilitiesCb);
197 }
198 
199 }  // namespace implementation
200 }  // namespace V1_1
201 }  // namespace measurement_corrections
202 }  // namespace gnss
203 }  // namespace hardware
204 }  // namespace android
205