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