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 #include <XtraSystemStatusObserver.h>
39 
40 #define MAX_URL_LEN 256
41 #define NMEA_SENTENCE_MAX_LENGTH 200
42 #define GLONASS_SV_ID_OFFSET 64
43 #define MAX_SATELLITES_IN_USE 12
44 #define LOC_NI_NO_RESPONSE_TIME 20
45 #define LOC_GPS_NI_RESPONSE_IGNORE 4
46 
47 class GnssAdapter;
48 
49 typedef struct {
50     pthread_t               thread;        /* NI thread */
51     uint32_t                respTimeLeft;  /* examine time for NI response */
52     bool                    respRecvd;     /* NI User reponse received or not from Java layer*/
53     void*                   rawRequest;
54     uint32_t                reqID;         /* ID to check against response */
55     GnssNiResponse          resp;
56     pthread_cond_t          tCond;
57     pthread_mutex_t         tLock;
58     GnssAdapter*            adapter;
59 } NiSession;
60 typedef struct {
61     NiSession session;    /* SUPL NI Session */
62     NiSession sessionEs;  /* Emergency SUPL NI Session */
63     uint32_t reqIDCounter;
64 } NiData;
65 
66 typedef enum {
67     NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
68     NMEA_PROVIDER_MP      // Modem Processor Provider of NMEA
69 } NmeaProviderType;
70 typedef struct {
71     GnssSvType svType;
72     const char* talker;
73     uint64_t mask;
74     uint32_t svIdOffset;
75 } NmeaSvMeta;
76 
77 using namespace loc_core;
78 
79 namespace loc_core {
80     class SystemStatus;
81 }
82 
83 class GnssAdapter : public LocAdapterBase {
84     /* ==== ULP ============================================================================ */
85     UlpProxyBase* mUlpProxy;
86 
87     /* ==== CLIENT ========================================================================= */
88     typedef std::map<LocationAPI*, LocationCallbacks> ClientDataMap;
89     ClientDataMap mClientData;
90 
91     /* ==== TRACKING ======================================================================= */
92     LocationSessionMap mTrackingSessions;
93     LocPosMode mUlpPositionMode;
94     GnssSvUsedInPosition mGnssSvIdUsedInPosition;
95     bool mGnssSvIdUsedInPosAvail;
96 
97     /* ==== CONTROL ======================================================================== */
98     LocationControlCallbacks mControlCallbacks;
99     uint32_t mPowerVoteId;
100     uint32_t mNmeaMask;
101 
102     /* ==== NI ============================================================================= */
103     NiData mNiData;
104 
105     /* ==== AGPS ========================================================*/
106     // This must be initialized via initAgps()
107     AgpsManager mAgpsManager;
108     AgpsCbInfo mAgpsCbInfo;
109 
110     /* === SystemStatus ===================================================================== */
111     SystemStatus* mSystemStatus;
112     XtraSystemStatusObserver mXtraObserver;
113 
114     /*==== CONVERSION ===================================================================*/
115     static void convertOptions(LocPosMode& out, const LocationOptions& options);
116     static void convertLocation(Location& out, const LocGpsLocation& locGpsLocation,
117                                 const GpsLocationExtended& locationExtended,
118                                 const LocPosTechMask techMask);
119     static void convertLocationInfo(GnssLocationInfoNotification& out,
120                                     const GpsLocationExtended& locationExtended);
121 
122 public:
123 
124     GnssAdapter();
~GnssAdapter()125     virtual inline ~GnssAdapter() { delete mUlpProxy; }
126 
127     /* ==== SSR ============================================================================ */
128     /* ======== EVENTS ====(Called from QMI Thread)========================================= */
129     virtual void handleEngineUpEvent();
130     /* ======== UTILITIES ================================================================== */
131     void restartSessions();
132 
133     /* ==== ULP ============================================================================ */
134     /* ======== COMMANDS ====(Called from ULP Thread)==================================== */
135     virtual void setUlpProxyCommand(UlpProxyBase* ulp);
136     /* ======== UTILITIES ================================================================== */
137     void setUlpProxy(UlpProxyBase* ulp);
getUlpProxy()138     inline UlpProxyBase* getUlpProxy() { return mUlpProxy; }
139 
140     /* ==== CLIENT ========================================================================= */
141     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
142     void addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks);
143     void removeClientCommand(LocationAPI* client);
144     void requestCapabilitiesCommand(LocationAPI* client);
145     /* ======== UTILITIES ================================================================== */
146     void saveClient(LocationAPI* client, const LocationCallbacks& callbacks);
147     void eraseClient(LocationAPI* client);
148     void updateClientsEventMask();
149     void stopClientSessions(LocationAPI* client);
150     LocationCallbacks getClientCallbacks(LocationAPI* client);
151     LocationCapabilitiesMask getCapabilities();
152     void broadcastCapabilities(LocationCapabilitiesMask);
153 
154     /* ==== TRACKING ======================================================================= */
155     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
156     uint32_t startTrackingCommand(LocationAPI* client, LocationOptions& options);
157     void updateTrackingOptionsCommand(LocationAPI* client, uint32_t id, LocationOptions& options);
158     void stopTrackingCommand(LocationAPI* client, uint32_t id);
159     /* ======================(Called from ULP Thread)======================================= */
160     virtual void setPositionModeCommand(LocPosMode& locPosMode);
161     virtual void startTrackingCommand();
162     virtual void stopTrackingCommand();
163     virtual void getZppCommand();
164     /* ======== RESPONSES ================================================================== */
165     void reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId);
166     /* ======== UTILITIES ================================================================== */
167     bool hasTrackingCallback(LocationAPI* client);
168     bool hasMeasurementsCallback(LocationAPI* client);
169     bool isTrackingSession(LocationAPI* client, uint32_t sessionId);
170     void saveTrackingSession(LocationAPI* client, uint32_t sessionId,
171                              const LocationOptions& options);
172     void eraseTrackingSession(LocationAPI* client, uint32_t sessionId);
setUlpPositionMode(const LocPosMode & mode)173     void setUlpPositionMode(const LocPosMode& mode) { mUlpPositionMode = mode; }
getUlpPositionMode()174     LocPosMode& getUlpPositionMode() { return mUlpPositionMode; }
175     LocationError startTrackingMultiplex(const LocationOptions& options);
176     LocationError startTracking(const LocationOptions& options);
177     LocationError stopTrackingMultiplex(LocationAPI* client, uint32_t id);
178     LocationError stopTracking();
179     LocationError updateTrackingMultiplex(LocationAPI* client, uint32_t id,
180                                           const LocationOptions& options);
181 
182     /* ==== NI ============================================================================= */
183     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
184     void gnssNiResponseCommand(LocationAPI* client, uint32_t id, GnssNiResponse response);
185     /* ======================(Called from NI Thread)======================================== */
186     void gnssNiResponseCommand(GnssNiResponse response, void* rawRequest);
187     /* ======== UTILITIES ================================================================== */
188     bool hasNiNotifyCallback(LocationAPI* client);
getNiData()189     NiData& getNiData() { return mNiData; }
190 
191     /* ==== CONTROL ======================================================================== */
192     /* ======== COMMANDS ====(Called from Client Thread)==================================== */
193     uint32_t enableCommand(LocationTechnologyType techType);
194     void disableCommand(uint32_t id);
195     void setControlCallbacksCommand(LocationControlCallbacks& controlCallbacks);
196     void readConfigCommand();
197     void setConfigCommand();
198     uint32_t* gnssUpdateConfigCommand(GnssConfig config);
199     uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
200 
201     void initAgpsCommand(const AgpsCbInfo& cbInfo);
202     void dataConnOpenCommand(
203             AGpsExtType agpsType,
204             const char* apnName, int apnLen, LocApnIpType ipType);
205     void dataConnClosedCommand(AGpsExtType agpsType);
206     void dataConnFailedCommand(AGpsExtType agpsType);
207 
208     /* ======== RESPONSES ================================================================== */
209     void reportResponse(LocationError err, uint32_t sessionId);
210     void reportResponse(size_t count, LocationError* errs, uint32_t* ids);
211     /* ======== UTILITIES ================================================================== */
getControlCallbacks()212     LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
setControlCallbacks(const LocationControlCallbacks & controlCallbacks)213     void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
214     { mControlCallbacks = controlCallbacks; }
setPowerVoteId(uint32_t id)215     void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
getPowerVoteId()216     uint32_t getPowerVoteId() { return mPowerVoteId; }
217     bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress);
218 
219     /* ==== REPORTS ======================================================================== */
220     /* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */
221     virtual void reportPositionEvent(const UlpLocation& ulpLocation,
222                                      const GpsLocationExtended& locationExtended,
223                                      enum loc_sess_status status,
224                                      LocPosTechMask techMask,
225                                      bool fromUlp=false);
226     virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromUlp=false);
227     virtual void reportNmeaEvent(const char* nmea, size_t length, bool fromUlp=false);
228     virtual bool requestNiNotifyEvent(const GnssNiNotification& notify, const void* data);
229     virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
230                                                 int msInWeek);
231     virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
232     virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
233 
234     virtual bool requestATL(int connHandle, LocAGpsType agps_type);
235     virtual bool releaseATL(int connHandle);
236     virtual bool requestSuplES(int connHandle);
237     virtual bool reportDataCallOpened();
238     virtual bool reportDataCallClosed();
239 
240     /* ======== UTILITIES ================================================================= */
241     void reportPosition(const UlpLocation &ulpLocation,
242                         const GpsLocationExtended &locationExtended,
243                         enum loc_sess_status status,
244                         LocPosTechMask techMask);
245     void reportSv(GnssSvNotification& svNotify);
246     void reportNmea(const char* nmea, size_t length);
247     bool requestNiNotify(const GnssNiNotification& notify, const void* data);
248     void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
249 
250     /*======== GNSSDEBUG ================================================================*/
251     bool getDebugReport(GnssDebugReport& report);
252     /* get AGC information from system status and fill it */
253     void getAgcInformation(GnssMeasurementsNotification& measurements, int msInWeek);
254 
255     /*==== SYSTEM STATUS ================================================================*/
getSystemStatus(void)256     inline SystemStatus* getSystemStatus(void) { return mSystemStatus; }
257 
258     /*==== CONVERSION ===================================================================*/
259     static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock);
260     static GnssConfigGpsLock convertGpsLock(const uint32_t gpsLock);
261     static uint32_t convertSuplVersion(const GnssConfigSuplVersion suplVersion);
262     static GnssConfigSuplVersion convertSuplVersion(const uint32_t suplVersion);
263     static uint32_t convertLppProfile(const GnssConfigLppProfile lppProfile);
264     static GnssConfigLppProfile convertLppProfile(const uint32_t lppProfile);
265     static uint32_t convertEP4ES(const GnssConfigEmergencyPdnForEmergencySupl);
266     static uint32_t convertSuplEs(const GnssConfigSuplEmergencyServices suplEmergencyServices);
267     static uint32_t convertLppeCp(const GnssConfigLppeControlPlaneMask lppeControlPlaneMask);
268     static GnssConfigLppeControlPlaneMask convertLppeCp(const uint32_t lppeControlPlaneMask);
269     static uint32_t convertLppeUp(const GnssConfigLppeUserPlaneMask lppeUserPlaneMask);
270     static GnssConfigLppeUserPlaneMask convertLppeUp(const uint32_t lppeUserPlaneMask);
271     static uint32_t convertAGloProt(const GnssConfigAGlonassPositionProtocolMask);
272     static uint32_t convertSuplMode(const GnssConfigSuplModeMask suplModeMask);
273     static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
274                                      const GnssSvType& in_constellation,
275                                      const SystemStatusReports& in);
276 
277     void injectLocationCommand(double latitude, double longitude, float accuracy);
278     void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
279 
280 };
281 
282 #endif //GNSS_ADAPTER_H
283