1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation, nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 #ifndef GNSS_ADAPTER_H
30 #define GNSS_ADAPTER_H
31 
32 #include <LocAdapterBase.h>
33 #include <LocDualContext.h>
34 #include <UlpProxyBase.h>
35 #include <LocationAPI.h>
36 #include <Agps.h>
37 #include <SystemStatus.h>
38 
39 #define MAX_URL_LEN 256
40 #define NMEA_SENTENCE_MAX_LENGTH 200
41 #define GLONASS_SV_ID_OFFSET 64
42 #define MAX_SATELLITES_IN_USE 12
43 #define LOC_NI_NO_RESPONSE_TIME 20
44 #define LOC_GPS_NI_RESPONSE_IGNORE 4
45 
46 class GnssAdapter;
47 
48 typedef struct {
49     pthread_t               thread;        /* NI thread */
50     uint32_t                respTimeLeft;  /* examine time for NI response */
51     bool                    respRecvd;     /* NI User reponse received or not from Java layer*/
52     void*                   rawRequest;
53     uint32_t                reqID;         /* ID to check against response */
54     GnssNiResponse          resp;
55     pthread_cond_t          tCond;
56     pthread_mutex_t         tLock;
57     GnssAdapter*            adapter;
58 } NiSession;
59 typedef struct {
60     NiSession session;    /* SUPL NI Session */
61     NiSession sessionEs;  /* Emergency SUPL NI Session */
62     uint32_t reqIDCounter;
63 } NiData;
64 
65 typedef enum {
66     NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
67     NMEA_PROVIDER_MP      // Modem Processor Provider of NMEA
68 } NmeaProviderType;
69 typedef struct {
70     GnssSvType svType;
71     const char* talker;
72     uint64_t mask;
73     uint32_t svIdOffset;
74 } NmeaSvMeta;
75 
76 using namespace loc_core;
77 
78 class GnssAdapter : public LocAdapterBase {
79     /* ==== ULP ============================================================================ */
80     UlpProxyBase* mUlpProxy;
81 
82     /* ==== CLIENT ========================================================================= */
83     typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
84     ClientDataMap mClientData;
85 
86     /* ==== TRACKING ======================================================================= */
87     LocationSessionMap mTrackingSessions;
88     LocPosMode mUlpPositionMode;
89     GnssSvUsedInPosition mGnssSvIdUsedInPosition;
90     bool mGnssSvIdUsedInPosAvail;
91 
92     /* ==== CONTROL ======================================================================== */
93     LocationControlCallbacks mControlCallbacks;
94     uint32_t mPowerVoteId;
95 
96     /* ==== NI ============================================================================= */
97     NiData mNiData;
98 
99     /* ==== AGPS ========================================================*/
100     // This must be initialized via initAgps()
101     AgpsManager mAgpsManager;
102     bool mAgpsInitialized;
103 
104     /*==== CONVERSION ===================================================================*/
105     static void convertOptions(LocPosMode& out, const LocationOptions& options);
106     static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
107                                 const GpsLocationExtended& locationExtended,
108                                 const LocPosTechMask techMask);
109     static void convertLocationInfo(GnssLocationInfoNotification& out,
110                                     const GpsLocationExtended& locationExtended);
111 
112 public:
113 
114     GnssAdapter();
115     virtual ~GnssAdapter();
116 
117     /* ==== SSR ============================================================================ */
118     /* ======== EVENTS ====(Called from QMI Thread)========================================= */
119     virtual void handleEngineUpEvent();
120     /* ======== UTILITIES ================================================================== */
121     void restartSessions();
122 
123     /* ==== ULP ============================================================================ */
124     /* ======== COMMANDS ====(Called from ULP Thread)==================================== */
125     virtual void setUlpProxyCommand(UlpProxyBase* ulp);
126     /* ======== UTILITIES ================================================================== */
127     void setUlpProxy(UlpProxyBase* ulp);
getUlpProxy()128     inline UlpProxyBase* getUlpProxy() { return mUlpProxy; }
129 
130     /* ==== CLIENT ========================================================================= */
131     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
132     void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
133     void removeClientCommand(LocationAPI* client);
134     void requestCapabilitiesCommand(LocationAPI* client);
135     /* ======== UTILITIES ================================================================== */
136     void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
137     void eraseClient(LocationAPI* client);
138     void updateClientsEventMask();
139     void stopClientSessions(LocationAPI* client);
140     LocationCallbacks getClientCallbacks(LocationAPI* client);
141 
142     /* ==== TRACKING ======================================================================= */
143     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
144     uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options);
145     void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options);
146     void stopTrackingCommand(LocationAPI* client, uint32_t id);
147     /* ======================(Called from ULP Thread)======================================= */
148     virtual void setPositionModeCommand(LocPosMode& locPosMode);
149     virtual void startTrackingCommand();
150     virtual void stopTrackingCommand();
151     virtual void getZppCommand();
152     /* ======== RESPONSES ================================================================== */
153     void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
154     /* ======== UTILITIES ================================================================== */
155     bool hasTrackingCallback(LocationAPI* client);
156     bool hasMeasurementsCallback(LocationAPI* client);
157     bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
158     void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
159                              const LocationOptions& options);
160     void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);
setUlpPositionMode(const LocPosMode & mode)161     void setUlpPositionMode(const LocPosMode& mode) { mUlpPositionMode = mode; }
getUlpPositionMode()162     LocPosMode& getUlpPositionMode() { return mUlpPositionMode; }
163     LocationError startTrackingMultiplex(const LocationOptions& options);
164     LocationError startTracking(const LocationOptions& options);
165     LocationError stopTrackingMultiplex(LocationAPI* client, uint32_t id);
166     LocationError stopTracking();
167     LocationError updateTrackingMultiplex(LocationAPI* client, uint32_t id,
168                                           const LocationOptions& options);
169 
170     /* ==== NI ============================================================================= */
171     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
172     void gnssNiResponseCommand(LocationAPI* client, uint32_t id, GnssNiResponse response);
173     /* ======================(Called from NI Thread)======================================== */
174     void gnssNiResponseCommand(GnssNiResponse response, void* rawRequest);
175     /* ======== UTILITIES ================================================================== */
176     bool hasNiNotifyCallback(LocationAPI* client);
getNiData()177     NiData& getNiData() { return mNiData; }
178 
179     /* ==== CONTROL ======================================================================== */
180     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
181     uint32_t enableCommand(LocationTechnologyType techType);
182     void disableCommand(uint32_t id);
183     void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
184     void readConfigCommand();
185     void setConfigCommand();
186     uint32_t* gnssUpdateConfigCommand(GnssConfig config);
187     uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
188 
189     void initAgpsCommand(void* statusV4Cb);
190     void dataConnOpenCommand(
191             AGpsExtType agpsType,
192             const char* apnName, int apnLen, LocApnIpType ipType);
193     void dataConnClosedCommand(AGpsExtType agpsType);
194     void dataConnFailedCommand(AGpsExtType agpsType);
setAgpsInitialized(bool value)195     inline void setAgpsInitialized(bool value) { mAgpsInitialized = value; }
getAgpsInitialized()196     inline bool getAgpsInitialized() { return mAgpsInitialized; }
197 
198     /* ======== RESPONSES ================================================================== */
199     void reportResponse(LocationError err, uint32_t sessionId);
200     void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
201     /* ======== UTILITIES ================================================================== */
getControlCallbacks()202     LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
setControlCallbacks(const LocationControlCallbacks & controlCallbacks)203     void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
204     { mControlCallbacks = controlCallbacks; }
setPowerVoteId(uint32_t id)205     void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
getPowerVoteId()206     uint32_t getPowerVoteId() { return mPowerVoteId; }
207     bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress);
208 
209     /* ==== REPORTS ======================================================================== */
210     /* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */
211     virtual void reportPositionEvent(const UlpLocation& ulpLocation,
212                                      const GpsLocationExtended& locationExtended,
213                                      enum loc_sess_status status,
214                                      LocPosTechMask techMask,
215                                      bool fromUlp=false);
216     virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
217     virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
218     virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
219     virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurementsNotify);
220     virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
221     virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
222 
223     virtual bool requestATL(int connHandle, LocAGpsType agps_type);
224     virtual bool releaseATL(int connHandle);
225     virtual bool requestSuplES(int connHandle);
226     virtual bool reportDataCallOpened();
227     virtual bool reportDataCallClosed();
228 
229     /* ======== UTILITIES ================================================================= */
230     bool needReport(const UlpLocation& ulpLocation,
231             enum loc_sess_status status, LocPosTechMask techMask);
232     void reportPosition(const UlpLocation &ulpLocation,
233                         const GpsLocationExtended &locationExtended,
234                         enum loc_sess_status status,
235                         LocPosTechMask techMask);
236     void reportSv(GnssSvNotification& svNotify);
237     void reportNmea(const char* nmea, size_t length);
238     bool requestNiNotify(const GnssNiNotification& notify, const void* data);
239     void reportGnssMeasurementData(const GnssMeasurementsNotification& measurementsNotify);
240 
241     /*======== GNSSDEBUG ================================================================*/
242     bool getDebugReport(GnssDebugReport& report);
243 
244     /*==== CONVERSION ===================================================================*/
245     static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
246     static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
247     static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
248     static GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
249     static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
250     static GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
251     static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
252     static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
253     static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
254     static GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
255     static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
256     static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
257     static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
258     static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
259     static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
260                                      const GnssSvType& in_constellation,
261                                      const SystemStatusReports& in);
262     void injectLocationCommand(double latitude, double longitude, float accuracy);
263     void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
264 
265 };
266 
267 #endif //GNSS_ADAPTER_H
268