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 ¬ification) = 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 ¬ification); 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 ¬ification); 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 ¬ification); 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 ¬ification); 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 ¬ification); 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