Home | History | Annotate | Download | only in libloc_api_50001
      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
     89     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
     96     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
    103     inline Notification(const int broadcast) :
    104         rcver(NULL), groupID(broadcast), rsrcStatus(RSRC_STATUS_MAX),
    105         postNotifyDelete(false) {}
    106 
    107     // convenient constructor
    108     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 
    133     inline AgpsState(const AgpsStateMachine *stateMachine) :
    134         mStateMachine(stateMachine),
    135         mReleasedState(NULL),
    136         mAcquiredState(NULL),
    137         mPendingState(NULL),
    138         mReleasingState(NULL) {}
    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);
    151     Servicer() {}
    152     Servicer(void *cb_func)
    153     { callback = (void(*)(void))(cb_func); }
    154     virtual ~Servicer(){}
    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);
    162     ExtServicer() {}
    163     ExtServicer(void *cb_func)
    164     { callbackExt = (int(*)(void *))(cb_func); }
    165     virtual ~ExtServicer(){}
    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);
    173     AGpsServicer() {}
    174     AGpsServicer(void *cb_func)
    175     { callbackAGps = (void(*)(AGpsStatus *))(cb_func); }
    176     virtual ~AGpsServicer(){}
    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);
    214     inline const char* getAPN() const { return (const char*)mAPN; }
    215     inline void setBearer(AGpsBearerType bearer) { mBearer = bearer; }
    216     inline AGpsBearerType getBearer() const { return mBearer; }
    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
    237     inline bool hasSubscribers() const
    238     { return !linked_list_empty(mSubscribers); }
    239 
    240     bool hasActiveSubscribers() const;
    241 
    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;
    263     inline void incRetries() {mRetries++;}
    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;
    273     inline Subscriber(const int id,
    274                       const AgpsStateMachine* stateMachine) :
    275         ID(id), mStateMachine(stateMachine) {}
    276     inline virtual ~Subscriber() {}
    277 
    278     virtual void setIPAddresses(uint32_t &v4, char* v6) = 0;
    279     virtual void setIPAddresses(struct sockaddr_storage& addr) = 0;
    280     inline virtual void setWifiInfo(char* ssid, char* password)
    281     { ssid[0] = 0; password[0] = 0; }
    282 
    283     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 
    290     virtual bool waitForCloseComplete() { return false; }
    291     virtual void setInactive() {}
    292     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 
    304     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 
    317     inline virtual void setIPAddresses(uint32_t &v4, char* v6)
    318     { v4 = ID; memcpy(v6, mIPv6Addr, sizeof(mIPv6Addr)); }
    319 
    320     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
    321     { addr.ss_family = AF_INET6;/*todo: convert mIPv6Addr into addr */ }
    322 
    323     virtual Subscriber* clone()
    324     {
    325         return new BITSubscriber(mStateMachine, ID, mIPv6Addr);
    326     }
    327 
    328     virtual bool equals(const Subscriber *s) const;
    329     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;
    336     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 
    344     inline virtual void setIPAddresses(uint32_t &v4, char* v6)
    345     { v4 = INADDR_NONE; v6[0] = 0; }
    346 
    347     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
    348     { addr.ss_family = AF_INET6; }
    349 
    350     inline virtual Subscriber* clone()
    351     {
    352         return new ATLSubscriber(ID, mStateMachine, mLocAdapter,
    353                                  mBackwardCompatibleMode);
    354     }
    355     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;
    364     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 
    380     inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
    381 
    382     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
    383     { addr.ss_family = AF_INET6; }
    384 
    385     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 
    397     inline virtual bool waitForCloseComplete() { return true; }
    398 
    399     inline virtual void setInactive() { mIsInactive = true; }
    400     inline virtual bool isInactive() { return mIsInactive; }
    401 
    402     virtual Subscriber* clone()
    403     {
    404         return new WIFISubscriber(mStateMachine, mSSID, mPassword, senderId);
    405     }
    406     inline virtual ~WIFISubscriber(){}
    407 };
    408 
    409 struct DSSubscriber : public Subscriber {
    410     bool mIsInactive;
    411     inline DSSubscriber(const AgpsStateMachine *stateMachine,
    412                          const int id) :
    413         Subscriber(id, stateMachine)
    414     {
    415         mIsInactive = false;
    416     }
    417     inline virtual void setIPAddresses(uint32_t &v4, char* v6) {}
    418     inline virtual void setIPAddresses(struct sockaddr_storage& addr)
    419     { addr.ss_family = AF_INET6; }
    420     virtual Subscriber* clone()
    421     {return new DSSubscriber(mStateMachine, ID);}
    422     virtual bool notifyRsrcStatus(Notification &notification);
    423     inline virtual bool waitForCloseComplete() { return true; }
    424     virtual void setInactive();
    425     inline virtual bool isInactive()
    426     { return mIsInactive; }
    427     inline virtual ~DSSubscriber(){}
    428     inline virtual char *whoami() {return (char*)"DSSubscriber";}
    429 };
    430 
    431 #endif //__LOC_ENG_AGPS_H__
    432