• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2011-2013, 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 __LOC_ENG_AGPS_H__
31 #define __LOC_ENG_AGPS_H__
32 
33 #include <stdbool.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <arpa/inet.h>
37 #include <hardware/gps.h>
38 #include <gps_extended.h>
39 #include <loc_core_log.h>
40 #include <linked_list.h>
41 #include <loc_timer.h>
42 #include <LocEngAdapter.h>
43 
44 // forward declaration
45 class AgpsStateMachine;
46 class Subscriber;
47 
48 // NIF resource events
49 typedef enum {
50     RSRC_SUBSCRIBE,
51     RSRC_UNSUBSCRIBE,
52     RSRC_GRANTED,
53     RSRC_RELEASED,
54     RSRC_DENIED,
55     RSRC_STATUS_MAX
56 } AgpsRsrcStatus;
57 
58 typedef enum {
59     servicerTypeNoCbParam,
60     servicerTypeAgps,
61     servicerTypeExt
62 }servicerType;
63 
64 //DS Callback struct
65 typedef struct {
66     LocEngAdapter *mAdapter;
67     AGpsStatusValue action;
68 }dsCbData;
69 
70 // information bundle for subscribers
71 struct Notification {
72     // goes to every subscriber
73     static const int BROADCAST_ALL;
74     // goes to every ACTIVE subscriber
75     static const int BROADCAST_ACTIVE;
76     // goes to every INACTIVE subscriber
77     static const int BROADCAST_INACTIVE;
78 
79     // go to a specific subscriber
80     const Subscriber* rcver;
81     // broadcast
82     const int groupID;
83     // the new resource status event
84     const AgpsRsrcStatus rsrcStatus;
85     // should the subscriber be deleted after the notification
86     const bool postNotifyDelete;
87 
88     // convenient constructor
NotificationNotification89     inline Notification(const int broadcast,
90                         const AgpsRsrcStatus status,
91                         const bool deleteAfterwards) :
92         rcver(NULL), groupID(broadcast), rsrcStatus(status),
93         postNotifyDelete(deleteAfterwards) {}
94 
95     // convenient constructor
NotificationNotification96     inline Notification(const Subscriber* subscriber,
97                         const AgpsRsrcStatus status,
98                         const bool deleteAfterwards) :
99         rcver(subscriber), groupID(-1), rsrcStatus(status),
100         postNotifyDelete(deleteAfterwards) {}
101 
102     // convenient constructor
NotificationNotification103     inline Notification(const int broadcast) :
104         rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX),
105         postNotifyDelete(false) {}
106 
107     // convenient constructor
NotificationNotification108     inline Notification(const Subscriber* subscriber) :
109         rcver(subscriber), groupID(-1), rsrcStatus(RSRC_STATUS_MAX),
110         postNotifyDelete(false) {}
111 };
112 
113 class AgpsState {
114     // allows AgpsStateMachine to access private data
115     // no class members are public.  We don't want
116     // anyone but state machine to use state.
117     friend class AgpsStateMachine;
118     friend class DSStateMachine;
119     // state transitions are done here.
120     // Each state implements its own transitions (of course).
121     inline virtual AgpsState* onRsrcEvent(AgpsRsrcStatus event, void* data) = 0;
122 
123 protected:
124     // handle back to state machine
125     const AgpsStateMachine* mStateMachine;
126     // each state has pointers to all 3 states
127     // one of which is to itself.
128     AgpsState* mReleasedState;
129     AgpsState* mAcquiredState;
130     AgpsState* mPendingState;
131     AgpsState* mReleasingState;
132 
AgpsState(const AgpsStateMachine * stateMachine)133     inline AgpsState(const AgpsStateMachine *stateMachine) :
134         mStateMachine(stateMachine),
135         mReleasedState(NULL),
136         mAcquiredState(NULL),
137         mPendingState(NULL),
138         mReleasingState(NULL) {}
~AgpsState()139     virtual ~AgpsState() {}
140 
141 public:
142     // for logging purpose
143     inline virtual char* whoami() = 0;
144 };
145 
146 class Servicer {
147     void (*callback)(void);
148 public:
149     static Servicer* getServicer(servicerType type, void *cb_func);
150     virtual int requestRsrc(void *cb_data);
Servicer()151     Servicer() {}
Servicer(void * cb_func)152     Servicer(void *cb_func)
153     { callback = (void(*)(void))(cb_func); }
~Servicer()154     virtual ~Servicer(){}
whoami()155     inline virtual char *whoami() {return (char*)"Servicer";}
156 };
157 
158 class ExtServicer : public Servicer {
159     int (*callbackExt)(void *cb_data);
160 public:
161     int requestRsrc(void *cb_data);
ExtServicer()162     ExtServicer() {}
ExtServicer(void * cb_func)163     ExtServicer(void *cb_func)
164     { callbackExt = (int(*)(void *))(cb_func); }
~ExtServicer()165     virtual ~ExtServicer(){}
whoami()166     inline virtual char *whoami() {return (char*)"ExtServicer";}
167 };
168 
169 class AGpsServicer : public Servicer {
170     void (*callbackAGps)(AGpsStatus* status);
171 public:
172     int requestRsrc(void *cb_data);
AGpsServicer()173     AGpsServicer() {}
AGpsServicer(void * cb_func)174     AGpsServicer(void *cb_func)
175     { callbackAGps = (void(*)(AGpsStatus *))(cb_func); }
~AGpsServicer()176     virtual ~AGpsServicer(){}
whoami()177     inline virtual char *whoami() {return (char*)"AGpsServicer";}
178 };
179 
180 class AgpsStateMachine {
181 protected:
182     // a linked list of subscribers.
183     void* mSubscribers;
184     //handle to whoever provides the service
185     Servicer *mServicer;
186     // allows AgpsState to access private data
187     // each state is really internal data to the
188     // state machine, so it should be able to
189     // access anything within the state machine.
190     friend class AgpsState;
191     // pointer to the current state.
192     AgpsState* mStatePtr;
193 private:
194     // NIF type: AGNSS or INTERNET.
195     const AGpsExtType mType;
196     // apn to the NIF.  Each state machine tracks
197     // resource state of a particular NIF.  For each
198     // NIF, there is also an active APN.
199     char* mAPN;
200     // for convenience, we don't do strlen each time.
201     unsigned int mAPNLen;
202     // bear
203     AGpsBearerType mBearer;
204     // ipv4 address for routing
205     bool mEnforceSingleSubscriber;
206 
207 public:
208     AgpsStateMachine(servicerType servType, void *cb_func,
209                      AGpsExtType type, bool enforceSingleSubscriber);
210     virtual ~AgpsStateMachine();
211 
212     // self explanatory methods below
213     void setAPN(const char* apn, unsigned int len);
getAPN()214     inline const char* getAPN() const { return (const char*)mAPN; }
setBearer(AGpsBearerType bearer)215     inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
getBearer()216     inline AGpsBearerType getBearer() const { return mBearer; }
getType()217     inline AGpsExtType getType() const { return (AGpsExtType)mType; }
218 
219     // someone, a ATL client or BIT, is asking for NIF
220     void subscribeRsrc(Subscriber *subscriber);
221 
222     // someone, a ATL client or BIT, is done with NIF
223     bool unsubscribeRsrc(Subscriber *subscriber);
224 
225     // add a subscriber in the linked list, if not already there.
226     void addSubscriber(Subscriber* subscriber) const;
227 
228     virtual void onRsrcEvent(AgpsRsrcStatus event);
229 
230     // put the data together and send the FW
231     virtual int sendRsrcRequest(AGpsStatusValue action) const;
232 
233     //if list is empty, linked_list_empty returns 1
234     //else if list is not empty, returns 0
235     //so hasSubscribers() returns 1 if list is not empty
236     //and returns 0 if list is empty
hasSubscribers()237     inline bool hasSubscribers() const
238     { return !linked_list_empty(mSubscribers); }
239 
240     bool hasActiveSubscribers() const;
241 
dropAllSubscribers()242     inline void dropAllSubscribers() const
243     { linked_list_flush(mSubscribers); }
244 
245     // private. Only a state gets to call this.
246     void notifySubscribers(Notification& notification) const;
247 
248 };
249 
250 class DSStateMachine : public AgpsStateMachine {
251     static const unsigned char MAX_START_DATA_CALL_RETRIES;
252     static const unsigned int DATA_CALL_RETRY_DELAY_MSEC;
253     LocEngAdapter* mLocAdapter;
254     unsigned char mRetries;
255 public:
256     DSStateMachine(servicerType type,
257                    void *cb_func,
258                    LocEngAdapter* adapterHandle);
259     int sendRsrcRequest(AGpsStatusValue action) const;
260     void onRsrcEvent(AgpsRsrcStatus event);
261     void retryCallback();
262     void informStatus(AgpsRsrcStatus status, int ID) const;
incRetries()263     inline void incRetries() {mRetries++;}
whoami()264     inline virtual char *whoami() {return (char*)"DSStateMachine";}
265 };
266 
267 // each subscriber is a AGPS client.  In the case of ATL, there could be
268 // multiple clients from modem.  In the case of BIT, there is only one
269 // cilent from BIT daemon.
270 struct Subscriber {
271     const uint32_t ID;
272     const AgpsStateMachine* mStateMachine;
SubscriberSubscriber273     inline Subscriber(const int id,
274                       const AgpsStateMachine* stateMachine) :
275         ID(id), mStateMachine(stateMachine) {}
~SubscriberSubscriber276     inline virtual ~Subscriber() {}
277 
278     virtual void setIPAddresses(uint32_t &v4, char* v6) = 0;
279     virtual void setIPAddresses(struct sockaddr_storage& addr) = 0;
setWifiInfoSubscriber280     inline virtual void setWifiInfo(char* ssid, char* password)
281     { ssid[0] = 0; password[0] = 0; }
282 
equalsSubscriber283     inline virtual bool equals(const Subscriber *s) const
284     { return ID == s->ID; }
285 
286     // notifies a subscriber a new NIF resource status, usually
287     // either GRANTE, DENIED, or RELEASED
288     virtual bool notifyRsrcStatus(Notification &notification) = 0;
289 
waitForCloseCompleteSubscriber290     virtual bool waitForCloseComplete() { return false; }
setInactiveSubscriber291     virtual void setInactive() {}
isInactiveSubscriber292     virtual bool isInactive() { return false; }
293 
294     virtual Subscriber* clone() = 0;
295     // checks if this notification is for me, i.e.
296     // either has my id, or has a broadcast id.
297     bool forMe(Notification &notification);
298 };
299 
300 // BITSubscriber, created with requests from BIT daemon
301 struct BITSubscriber : public Subscriber {
302     char mIPv6Addr[16];
303 
BITSubscriberBITSubscriber304     inline BITSubscriber(const AgpsStateMachine* stateMachine,
305                          unsigned int ipv4, char* ipv6) :
306         Subscriber(ipv4, stateMachine)
307     {
308         if (NULL == ipv6) {
309             mIPv6Addr[0] = 0;
310         } else {
311             memcpy(mIPv6Addr, ipv6, sizeof(mIPv6Addr));
312         }
313     }
314 
315     virtual bool notifyRsrcStatus(Notification &notification);
316 
setIPAddressesBITSubscriber317     inline virtual void setIPAddresses(uint32_t &v4, char* v6)
318     { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); }
319 
setIPAddressesBITSubscriber320     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
321     { addr.ss_family = AF_INET6;/*todo: convert mIPv6Addr into addr */ }
322 
cloneBITSubscriber323     virtual Subscriber* clone()
324     {
325         return new BITSubscriber(mStateMachine, ID, mIPv6Addr);
326     }
327 
328     virtual bool equals(const Subscriber *s) const;
~BITSubscriberBITSubscriber329     inline virtual ~BITSubscriber(){}
330 };
331 
332 // ATLSubscriber, created with requests from ATL
333 struct ATLSubscriber : public Subscriber {
334     const LocEngAdapter* mLocAdapter;
335     const bool mBackwardCompatibleMode;
ATLSubscriberATLSubscriber336     inline ATLSubscriber(const int id,
337                          const AgpsStateMachine* stateMachine,
338                          const LocEngAdapter* adapter,
339                          const bool compatibleMode) :
340         Subscriber(id, stateMachine), mLocAdapter(adapter),
341         mBackwardCompatibleMode(compatibleMode){}
342     virtual bool notifyRsrcStatus(Notification &notification);
343 
setIPAddressesATLSubscriber344     inline virtual void setIPAddresses(uint32_t &v4, char* v6)
345     { v4 = INADDR_NONE; v6[0] = 0; }
346 
setIPAddressesATLSubscriber347     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
348     { addr.ss_family = AF_INET6; }
349 
cloneATLSubscriber350     inline virtual Subscriber* clone()
351     {
352         return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
353                                  mBackwardCompatibleMode);
354     }
~ATLSubscriberATLSubscriber355     inline virtual ~ATLSubscriber(){}
356 };
357 
358 // WIFISubscriber, created with requests from MSAPM or QuIPC
359 struct WIFISubscriber : public Subscriber {
360     char * mSSID;
361     char * mPassword;
362     loc_if_req_sender_id_e_type senderId;
363     bool mIsInactive;
WIFISubscriberWIFISubscriber364     inline WIFISubscriber(const AgpsStateMachine* stateMachine,
365                          char * ssid, char * password, loc_if_req_sender_id_e_type sender_id) :
366         Subscriber(sender_id, stateMachine),
367         mSSID(NULL == ssid ? NULL : new char[SSID_BUF_SIZE]),
368         mPassword(NULL == password ? NULL : new char[SSID_BUF_SIZE]),
369         senderId(sender_id)
370     {
371       if (NULL != mSSID)
372           strlcpy(mSSID, ssid, SSID_BUF_SIZE);
373       if (NULL != mPassword)
374           strlcpy(mPassword, password, SSID_BUF_SIZE);
375       mIsInactive = false;
376     }
377 
378     virtual bool notifyRsrcStatus(Notification &notification);
379 
setIPAddressesWIFISubscriber380     inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
381 
setIPAddressesWIFISubscriber382     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
383     { addr.ss_family = AF_INET6; }
384 
setWifiInfoWIFISubscriber385     inline virtual void setWifiInfo(char* ssid, char* password)
386     {
387       if (NULL != mSSID)
388           strlcpy(ssid, mSSID, SSID_BUF_SIZE);
389       else
390           ssid[0] = '\0';
391       if (NULL != mPassword)
392           strlcpy(password, mPassword, SSID_BUF_SIZE);
393       else
394           password[0] = '\0';
395     }
396 
waitForCloseCompleteWIFISubscriber397     inline virtual bool waitForCloseComplete() { return true; }
398 
setInactiveWIFISubscriber399     inline virtual void setInactive() { mIsInactive = true; }
isInactiveWIFISubscriber400     inline virtual bool isInactive() { return mIsInactive; }
401 
cloneWIFISubscriber402     virtual Subscriber* clone()
403     {
404         return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
405     }
~WIFISubscriberWIFISubscriber406     inline virtual ~WIFISubscriber(){}
407 };
408 
409 struct DSSubscriber : public Subscriber {
410     bool mIsInactive;
DSSubscriberDSSubscriber411     inline DSSubscriber(const AgpsStateMachine *stateMachine,
412                          const int id) :
413         Subscriber(id, stateMachine)
414     {
415         mIsInactive = false;
416     }
setIPAddressesDSSubscriber417     inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
setIPAddressesDSSubscriber418     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
419     { addr.ss_family = AF_INET6; }
cloneDSSubscriber420     virtual Subscriber* clone()
421     {return new DSSubscriber(mStateMachine, ID);}
422     virtual bool notifyRsrcStatus(Notification &notification);
waitForCloseCompleteDSSubscriber423     inline virtual bool waitForCloseComplete() { return true; }
424     virtual void setInactive();
isInactiveDSSubscriber425     inline virtual bool isInactive()
426     { return mIsInactive; }
~DSSubscriberDSSubscriber427     inline virtual ~DSSubscriber(){}
whoamiDSSubscriber428     inline virtual char *whoami() {return (char*)"DSSubscriber";}
429 };
430 
431 #endif //__LOC_ENG_AGPS_H__
432