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
47class GnssAdapter;
48
49typedef 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;
60typedef struct {
61    NiSession session;    /* SUPL NI Session */
62    NiSession sessionEs;  /* Emergency SUPL NI Session */
63    uint32_t reqIDCounter;
64} NiData;
65
66typedef enum {
67    NMEA_PROVIDER_AP = 0, // Application Processor Provider of NMEA
68    NMEA_PROVIDER_MP      // Modem Processor Provider of NMEA
69} NmeaProviderType;
70typedef struct {
71    GnssSvType svType;
72    const char* talker;
73    uint64_t mask;
74    uint32_t svIdOffset;
75} NmeaSvMeta;
76
77using namespace loc_core;
78
79namespace loc_core {
80    class SystemStatus;
81}
82
83class 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
122public:
123
124    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);
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);
173    void setUlpPositionMode(const LocPosMode& mode) { mUlpPositionMode = mode; }
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);
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 ================================================================== */
212    LocationControlCallbacks& getControlCallbacks() { return mControlCallbacks; }
213    void setControlCallbacks(const LocationControlCallbacks& controlCallbacks)
214    { mControlCallbacks = controlCallbacks; }
215    void setPowerVoteId(uint32_t id) { mPowerVoteId = id; }
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 ================================================================*/
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