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