1/* Copyright (c) 2012-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
30#ifndef AGPS_H
31#define AGPS_H
32
33#include <functional>
34#include <list>
35#include <MsgTask.h>
36#include <gps_extended_c.h>
37#include <platform_lib_log_util.h>
38
39/* ATL callback function pointers
40 * Passed in by Adapter to AgpsManager */
41typedef std::function<void(
42        int handle, int isSuccess, char* apn,
43        AGpsBearerType bearerType, AGpsExtType agpsType)>  AgpsAtlOpenStatusCb;
44
45typedef std::function<void(int handle, int isSuccess)>     AgpsAtlCloseStatusCb;
46
47/* DS Client control APIs
48 * Passed in by Adapter to AgpsManager */
49typedef std::function<int(bool isDueToSSR)>  AgpsDSClientInitFn;
50typedef std::function<int()>                 AgpsDSClientOpenAndStartDataCallFn;
51typedef std::function<void()>                AgpsDSClientStopDataCallFn;
52typedef std::function<void()>                AgpsDSClientCloseDataCallFn;
53typedef std::function<void()>                AgpsDSClientReleaseFn;
54
55/* Post message to adapter's message queue */
56typedef std::function<void(LocMsg* msg)>     SendMsgToAdapterMsgQueueFn;
57
58/* AGPS States */
59typedef enum {
60    AGPS_STATE_INVALID = 0,
61    AGPS_STATE_RELEASED,
62    AGPS_STATE_PENDING,
63    AGPS_STATE_ACQUIRED,
64    AGPS_STATE_RELEASING
65} AgpsState;
66
67typedef enum {
68    AGPS_EVENT_INVALID = 0,
69    AGPS_EVENT_SUBSCRIBE,
70    AGPS_EVENT_UNSUBSCRIBE,
71    AGPS_EVENT_GRANTED,
72    AGPS_EVENT_RELEASED,
73    AGPS_EVENT_DENIED
74} AgpsEvent;
75
76/* Notification Types sent to subscribers */
77typedef enum {
78    AGPS_NOTIFICATION_TYPE_INVALID = 0,
79
80    /* Meant for all subscribers, either active or inactive */
81    AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS,
82
83    /* Meant for only inactive subscribers */
84    AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS,
85
86    /* Meant for only active subscribers */
87    AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS
88} AgpsNotificationType;
89
90/* Framework AGNSS interface
91 * This interface is defined in IAGnssCallback provided by
92 * Android Framework.
93 * Must be kept in sync with that interface. */
94namespace AgpsFrameworkInterface {
95
96    /** AGNSS type **/
97    enum AGnssType : uint8_t {
98        TYPE_SUPL         = 1,
99        TYPE_C2K          = 2
100    };
101
102    enum AGnssStatusValue : uint8_t {
103        /** GNSS requests data connection for AGNSS. */
104        REQUEST_AGNSS_DATA_CONN  = 1,
105        /** GNSS releases the AGNSS data connection. */
106        RELEASE_AGNSS_DATA_CONN  = 2,
107        /** AGNSS data connection initiated */
108        AGNSS_DATA_CONNECTED     = 3,
109        /** AGNSS data connection completed */
110        AGNSS_DATA_CONN_DONE     = 4,
111        /** AGNSS data connection failed */
112        AGNSS_DATA_CONN_FAILED   = 5
113    };
114
115    /*
116     * Represents the status of AGNSS augmented to support IPv4.
117     */
118    struct AGnssStatusIpV4 {
119        AGnssType type;
120        AGnssStatusValue status;
121        /*
122         * 32-bit IPv4 address.
123         */
124        unsigned int ipV4Addr;
125    };
126
127    /*
128     * Represents the status of AGNSS augmented to support IPv6.
129     */
130    struct AGnssStatusIpV6 {
131        AGnssType type;
132        AGnssStatusValue status;
133        /*
134         * 128-bit IPv6 address.
135         */
136        unsigned char ipV6Addr[16];
137    };
138
139    /*
140     * Callback with AGNSS(IpV4) status information.
141     *
142     * @param status Will be of type AGnssStatusIpV4.
143     */
144    typedef void (*AgnssStatusIpV4Cb)(AGnssStatusIpV4 status);
145
146    /*
147     * Callback with AGNSS(IpV6) status information.
148     *
149     * @param status Will be of type AGnssStatusIpV6.
150     */
151    typedef void (*AgnssStatusIpV6Cb)(AGnssStatusIpV6 status);
152}
153
154/* Classes in this header */
155class AgpsSubscriber;
156class AgpsManager;
157class AgpsStateMachine;
158class DSStateMachine;
159
160
161/* SUBSCRIBER
162 * Each Subscriber instance corresponds to one AGPS request,
163 * received by the AGPS state machine */
164class AgpsSubscriber {
165
166public:
167    int mConnHandle;
168
169    /* Does this subscriber wait for data call close complete,
170     * before being notified ATL close ?
171     * While waiting for data call close, subscriber will be in
172     * inactive state. */
173    bool mWaitForCloseComplete;
174    bool mIsInactive;
175
176    inline AgpsSubscriber(
177            int connHandle, bool waitForCloseComplete, bool isInactive) :
178            mConnHandle(connHandle),
179            mWaitForCloseComplete(waitForCloseComplete),
180            mIsInactive(isInactive) {}
181    inline virtual ~AgpsSubscriber() {}
182
183    inline virtual bool equals(const AgpsSubscriber *s) const
184    { return (mConnHandle == s->mConnHandle); }
185
186    inline virtual AgpsSubscriber* clone()
187    { return new AgpsSubscriber(
188            mConnHandle, mWaitForCloseComplete, mIsInactive); }
189};
190
191/* AGPS STATE MACHINE */
192class AgpsStateMachine {
193protected:
194    /* AGPS Manager instance, from where this state machine is created */
195    AgpsManager* mAgpsManager;
196
197    /* List of all subscribers for this State Machine.
198     * Once a subscriber is notified for ATL open/close status,
199     * it is deleted */
200    std::list<AgpsSubscriber*> mSubscriberList;
201
202    /* Current subscriber, whose request this State Machine is
203     * currently processing */
204    AgpsSubscriber* mCurrentSubscriber;
205
206    /* Current state for this state machine */
207    AgpsState mState;
208
209private:
210    /* AGPS Type for this state machine
211       LOC_AGPS_TYPE_ANY           0
212       LOC_AGPS_TYPE_SUPL          1
213       LOC_AGPS_TYPE_WWAN_ANY      3
214       LOC_AGPS_TYPE_SUPL_ES       5 */
215    AGpsExtType mAgpsType;
216
217    /* APN and IP Type info for AGPS Call */
218    char* mAPN;
219    unsigned int mAPNLen;
220    AGpsBearerType mBearer;
221
222public:
223    /* CONSTRUCTOR */
224    AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType):
225        mAgpsManager(agpsManager), mSubscriberList(),
226        mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED),
227        mAgpsType(agpsType), mAPN(NULL), mAPNLen(0),
228        mBearer(AGPS_APN_BEARER_INVALID) {};
229
230    virtual ~AgpsStateMachine() { if(NULL != mAPN) delete[] mAPN; };
231
232    /* Getter/Setter methods */
233    void setAPN(char* apn, unsigned int len);
234    inline char* getAPN() const { return (char*)mAPN; }
235    inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
236    inline AGpsBearerType getBearer() const { return mBearer; }
237    inline AGpsExtType getType() const { return mAgpsType; }
238    inline void setCurrentSubscriber(AgpsSubscriber* subscriber)
239    { mCurrentSubscriber = subscriber; }
240
241    /* Fetch subscriber with specified handle */
242    AgpsSubscriber* getSubscriber(int connHandle);
243
244    /* Fetch first active or inactive subscriber in list
245     * isInactive = true : fetch first inactive subscriber
246     * isInactive = false : fetch first active subscriber */
247    AgpsSubscriber* getFirstSubscriber(bool isInactive);
248
249    /* Process LOC AGPS Event being passed in
250     * onRsrcEvent */
251    virtual void processAgpsEvent(AgpsEvent event);
252
253    /* Drop all subscribers, in case of Modem SSR */
254    void dropAllSubscribers();
255
256protected:
257    /* Remove the specified subscriber from list if present.
258     * Also delete the subscriber instance. */
259    void deleteSubscriber(AgpsSubscriber* subscriber);
260
261private:
262    /* Send call setup request to framework
263     * sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
264     * sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
265    virtual int requestOrReleaseDataConn(bool request);
266
267    /* Individual event processing methods */
268    void processAgpsEventSubscribe();
269    void processAgpsEventUnsubscribe();
270    void processAgpsEventGranted();
271    void processAgpsEventReleased();
272    void processAgpsEventDenied();
273
274    /* Clone the passed in subscriber and add to the subscriber list
275     * if not already present */
276    void addSubscriber(AgpsSubscriber* subscriber);
277
278    /* Notify subscribers about AGPS events */
279    void notifyAllSubscribers(
280            AgpsEvent event, bool deleteSubscriberPostNotify,
281            AgpsNotificationType notificationType);
282    virtual void notifyEventToSubscriber(
283            AgpsEvent event, AgpsSubscriber* subscriber,
284            bool deleteSubscriberPostNotify);
285
286    /* Do we have any subscribers in active state */
287    bool anyActiveSubscribers();
288
289    /* Transition state */
290    void transitionState(AgpsState newState);
291};
292
293/* DS STATE MACHINE */
294class DSStateMachine : public AgpsStateMachine {
295
296private:
297    static const int MAX_START_DATA_CALL_RETRIES;
298    static const int DATA_CALL_RETRY_DELAY_MSEC;
299
300    int mRetries;
301
302public:
303    /* CONSTRUCTOR */
304    DSStateMachine(AgpsManager* agpsManager):
305        AgpsStateMachine(agpsManager, LOC_AGPS_TYPE_SUPL_ES), mRetries(0) {}
306
307    /* Overridden method
308     * DS SM needs to handle one event differently */
309    void processAgpsEvent(AgpsEvent event);
310
311    /* Retry callback, used in case call failure */
312    void retryCallback();
313
314private:
315    /* Overridden method, different functionality for DS SM
316     * Send call setup request to framework
317     * sendRsrcRequest(LOC_GPS_REQUEST_AGPS_DATA_CONN)
318     * sendRsrcRequest(LOC_GPS_RELEASE_AGPS_DATA_CONN) */
319    int requestOrReleaseDataConn(bool request);
320
321    /* Overridden method, different functionality for DS SM */
322    void notifyEventToSubscriber(
323            AgpsEvent event, AgpsSubscriber* subscriber,
324            bool deleteSubscriberPostNotify);
325};
326
327/* LOC AGPS MANAGER */
328class AgpsManager {
329
330    friend class AgpsStateMachine;
331    friend class DSStateMachine;
332
333public:
334    /* CONSTRUCTOR */
335    AgpsManager():
336        mFrameworkStatusV4Cb(NULL),
337        mAtlOpenStatusCb(), mAtlCloseStatusCb(),
338        mDSClientInitFn(), mDSClientOpenAndStartDataCallFn(),
339        mDSClientStopDataCallFn(), mDSClientCloseDataCallFn(), mDSClientReleaseFn(),
340        mSendMsgToAdapterQueueFn(),
341        mAgnssNif(NULL), mInternetNif(NULL), mDsNif(NULL) {}
342
343    /* Register callbacks */
344    void registerCallbacks(
345            AgpsFrameworkInterface::AgnssStatusIpV4Cb
346                                                frameworkStatusV4Cb,
347
348            AgpsAtlOpenStatusCb                 atlOpenStatusCb,
349            AgpsAtlCloseStatusCb                atlCloseStatusCb,
350
351            AgpsDSClientInitFn                  dsClientInitFn,
352            AgpsDSClientOpenAndStartDataCallFn  dsClientOpenAndStartDataCallFn,
353            AgpsDSClientStopDataCallFn          dsClientStopDataCallFn,
354            AgpsDSClientCloseDataCallFn         dsClientCloseDataCallFn,
355            AgpsDSClientReleaseFn               dsClientReleaseFn,
356
357            SendMsgToAdapterMsgQueueFn          sendMsgToAdapterQueueFn ){
358
359        mFrameworkStatusV4Cb = frameworkStatusV4Cb;
360
361        mAtlOpenStatusCb = atlOpenStatusCb;
362        mAtlCloseStatusCb = atlCloseStatusCb;
363
364        mDSClientInitFn = dsClientInitFn;
365        mDSClientOpenAndStartDataCallFn = dsClientOpenAndStartDataCallFn;
366        mDSClientStopDataCallFn = dsClientStopDataCallFn;
367        mDSClientCloseDataCallFn = dsClientCloseDataCallFn;
368        mDSClientReleaseFn = dsClientReleaseFn;
369
370        mSendMsgToAdapterQueueFn = sendMsgToAdapterQueueFn;
371    }
372
373    /* Create all AGPS state machines */
374    void createAgpsStateMachines();
375
376    /* Process incoming ATL requests */
377    void requestATL(int connHandle, AGpsExtType agpsType);
378    void releaseATL(int connHandle);
379
380    /* Process incoming DS Client data call events */
381    void reportDataCallOpened();
382    void reportDataCallClosed();
383
384    /* Process incoming framework data call events */
385    void reportAtlOpenSuccess(
386            AGpsExtType agpsType, char* apnName, int apnLen,
387            LocApnIpType ipType);
388    void reportAtlOpenFailed(AGpsExtType agpsType);
389    void reportAtlClosed(AGpsExtType agpsType);
390
391    /* Handle Modem SSR */
392    void handleModemSSR();
393
394protected:
395    AgpsFrameworkInterface::AgnssStatusIpV4Cb mFrameworkStatusV4Cb;
396
397    AgpsAtlOpenStatusCb   mAtlOpenStatusCb;
398    AgpsAtlCloseStatusCb  mAtlCloseStatusCb;
399
400    AgpsDSClientInitFn                  mDSClientInitFn;
401    AgpsDSClientOpenAndStartDataCallFn  mDSClientOpenAndStartDataCallFn;
402    AgpsDSClientStopDataCallFn          mDSClientStopDataCallFn;
403    AgpsDSClientCloseDataCallFn         mDSClientCloseDataCallFn;
404    AgpsDSClientReleaseFn               mDSClientReleaseFn;
405
406    SendMsgToAdapterMsgQueueFn          mSendMsgToAdapterQueueFn;
407
408    AgpsStateMachine*   mAgnssNif;
409    AgpsStateMachine*   mInternetNif;
410    AgpsStateMachine*   mDsNif;
411
412private:
413    /* Fetch state machine for handling request ATL call */
414    AgpsStateMachine* getAgpsStateMachine(AGpsExtType agpsType);
415};
416
417/* Request SUPL/INTERNET/SUPL_ES ATL
418 * This LocMsg is defined in this header since it has to be used from more
419 * than one place, other Agps LocMsg are restricted to GnssAdapter and
420 * declared inline */
421struct AgpsMsgRequestATL: public LocMsg {
422
423    AgpsManager* mAgpsManager;
424    int mConnHandle;
425    AGpsExtType mAgpsType;
426
427    inline AgpsMsgRequestATL(AgpsManager* agpsManager, int connHandle,
428            AGpsExtType agpsType) :
429            LocMsg(), mAgpsManager(agpsManager), mConnHandle(connHandle), mAgpsType(
430                    agpsType) {
431
432        LOC_LOGV("AgpsMsgRequestATL");
433    }
434
435    inline virtual void proc() const {
436
437        LOC_LOGV("AgpsMsgRequestATL::proc()");
438        mAgpsManager->requestATL(mConnHandle, mAgpsType);
439    }
440};
441
442namespace AgpsUtils {
443
444AGpsBearerType ipTypeToBearerType(LocApnIpType ipType);
445LocApnIpType bearerTypeToIpType(AGpsBearerType bearerType);
446
447}
448
449#endif /* AGPS_H */
450