/*****************************************************************************
 * Copyright (C) Gemalto M2M GmbH
 *****************************************************************************
 * Project: IMC-RIL-Driver
 *****************************************************************************
 * Author : Wireless Modules RD SW A2
 *****************************************************************************
 * $Workfile: Y:/z_ms-d/src/working/Quinn/RilDrv/GpsHand.h $
 * $Revision: /main/ms-d/20 $
 *     $Date: 2013-05-14 16:27:03 $
 *   $Author: pmackent $
 *****************************************************************************
 * Target:
 *  Microsoft Windows Mobile 5.0
 *****************************************************************************
 * Description:
 *  Gemalto IMC RIL
 *****************************************************************************
 *
 * $Log: Y:/z_ms-d/src/working/Quinn/RilDrv/GpsHand.h$ 
 * 
 * /main/ms-d/20   2013-05-14 16:27:03   pmackent 
 * GPS/GLONASS setting need reboot; ensure GPS antenna is on auto-mode
 *
 * /main/ms-d/19   2013-04-25 13:18:43   pmackent
 * No GPS AT commands on emergency calls (IPIS100087126)
 *
 * /main/ms-d/18   2012-10-22 11:18:03   pmackent
 * Additional configurable delay after AGPS download
 *
 * /main/ms-d/17   2012-09-18 09:26:07   pmackent
 * Use AT^SGPSC instead of AT^SGPSS
 *
 * /main/ms-d/16   2012-08-13 16:02:28   pmackent
 * New AHS3 GPS features (Glonass, dead reckoning)
 *
 * /main/ms-d/15   2012-08-13 11:06:42   pmackent
 * Apply changes to NMEA frequency immediately (IPIS100081354)
 *
 * /main/ms-d/14   2011-07-22 16:26:00   ctna0256
 * Notification about GPS activities
 *
 * /main/ms-d/13   2011-01-18 15:06:22   ctna0256
 * New syntax for loading A-GPS files
 *
 * /main/ms-d/12   2010-12-15 10:43:54   ctna0256
 * Performed lint check
 *
 * /main/ms-d/11   2010-11-04 15:58:49   ctna0256
 * New registry key for AGPS file age
 *
 * /main/ms-d/10   2010-09-01 15:55:35   ctna0256
 * AGPS under CE6
 *
 * /main/ms-d/9   2010-08-24 10:47:27   ctna0256
 * Improved AGPS file download
 *
 * /main/ms-d/8   2010-08-20 10:41:30   ctna0256
 * Prevent deadlock between power manager and GPS handling
 *
 * /main/ms-d/7   2010-08-19 14:30:01   ctna0256
 * Implementation A-GPS for PH8
 *
 * /main/ms-d/6   2008-08-22 10:23:59   ctna0256
 * Set Cinterion copyright text
 *
 * /main/ms-d/5   2008-08-21 09:34:34   ctna0256
 * Prepared for new disclaimer handling
 *
 * /main/ms-d/4   2008-01-29 11:36:42   kr36712
 * format correction
 *
 * /main/ms-d/3   2008-01-24 15:57:40   kr36712
 * integration GPS for MTLR and emergency call
 *
 * /main/ms-d/2   2007-11-26 17:05:46   kr36712
 * integration of GPS support
 * use of the mux protocol
 *
 * /main/ms-d/1   2006-10-25 16:53:39   wm36264
 * First transformation from classic RIL
 *
*/

//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008 Gemalto M2M GmbH
// Copyright (C) 2006-2008 Siemens AG
//
// Version: 1.0
// Date:    dummy
//
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
// GPS support of the in the Cinterion RIL driver is implemented via a
// dedicated multiplex channel of the HC25 Release 2 modules used for GPS
// only. Because the RIL driver needs to enable and disable GPS mode on that
// dedicated multiplex channel when the port is opened or closed that port
// is passed through the RIL so that in fact the RIL is providing the
// virtual GPS port but is passing the data directly to and from another
// virtual port provided by the multilpex driver. Having direct control of
// the virtula GPS port gives the RIL the opprtunity to enable GPS mode only
// when it is really used which helps to reduce power consumption.
// Additional and more important the RIL is able to consider the GPS usage
// directly when handling the power management of the radio part. That is
// done as described in the following tables:
//
// ===========================================================================
// Module states when system is in power state D0
// ===========================================================================
//   RIL  |  GPS  |  Module state
// ===========================================================================
//   off  |  off  |  Fully switched off
// ---------------------------------------------------------------------------
//   off  |  on   |  Radio in airplane mode, GPS enabled
// ---------------------------------------------------------------------------
//   on   |  off  |  Radio on, GPS disabled
// ---------------------------------------------------------------------------
//   on   |  on   |  Radio on, GPS enabled
// ---------------------------------------------------------------------------
//
// ===========================================================================
// Module states when system is in power state D2/D3:
// ===========================================================================
//   RIL  |  GPS  |  Module state
// ===========================================================================
//   off  |  off  |  Fully switched off
// ---------------------------------------------------------------------------
//   off  |  on   |  Fully switched off
// ---------------------------------------------------------------------------
//   on   |  off  |  Radio on with some URCs disabled, GPS disabled
// ---------------------------------------------------------------------------
//   on   |  on   |  Radio on with some URCs disabled, GPS disabled
// ---------------------------------------------------------------------------
//
// Switching GPS mode off in suspend mode prevents the GPS unit from consuming
// while GPS information isn't really needed. But this has the disadvantage
// that the GPS unit needs to resynchronize with the GPS satellites after
// system resume. That can take up to 30 seconds before the first location
// update is available after system resume. If the following registry value
// is set to 1 the GPS unit is left active during suspend with the
// disadvantage of the power consumption but the advantage of the location
// update being available immediately after resume.
//
// [HKEY_LOCAL_MACHINE\Software\Microsoft\RIL]
//   "KeepGpsActiveOnSuspend"=dword:1
//
// If that registry value is set the RIL follows the following rules in
// system suspend mode:
//
// ===========================================================================
// Module states when system is in power state D2/D3 (KeepGpsActiveOnSuspend)
// ===========================================================================
//   RIL  |  GPS  |  Module state
// ===========================================================================
//   off  |  off  |  Fully switched off
// ---------------------------------------------------------------------------
//   off  |  on   |  Radio in airplane mode, GPS enabled
// ---------------------------------------------------------------------------
//   on   |  off  |  Radio on with some URCs disabled, GPS disabled
// ---------------------------------------------------------------------------
//   on   |  on   |  Radio on with some URCs disabled, GPS enabled
// ---------------------------------------------------------------------------
//
//////////////////////////////////////////////////////////////////////////////

//
// Handling of GPS service
//
#define GPS_ANTENNA_POWER_SUPPL_EXTERNAL            2   // at^sgpss=2
#define GPS_ANTENNA_POWER_SUPPL_MODULE              4   // at^sgpss=4
#define GPS_PASSIVE_ANTENNA_POWER_SUPPL_EXTERNAL    1   // at^sgpss=1
#define GPS_PASSIVE_ANTENNA_POWER_SUPPL_MODULE      3   // at^sgpss=3

// File name and default path for the AGPS file
#define AGPS_FILE_NAME   L"xtra.bin"
#define AGPS_DEFAULT_PATH L"\\"
// Number of URLs to try (1 default URL + 2 backup URLs)
#define NUM_AGPS_URLS   3
// Maximum expected length of the AGPS file
#define MAX_AGPS_FILE_LEN   64000
// Timeout (in ms) waiting for download of AGPS file (time for each URL)
#define AGPS_DEFAULT_DOWNLOAD_TIMEOUT  10000
// Default executable for download application
#define AGPS_DEFAULT_DOWNLOAD_EXE  L"agps_download.exe"
// Delay (in ms) for the RIL to wait after download of AGPS file
#define AGPS_DEFAULT_DOWNLOAD_DELAY  100

// Name of the default URL where the latest A-GPS file is available. An
// empty string indicates, that the RIL won't do a download per default.
#define AGPS_DEFAULT_URL L""
// If the default URL should be the GPSone download server, uncomment
// the line below instead of the #define above.
//#define AGPS_DEFAULT_URL L"http://xtra1.gpsonextra.net/xtra.bin"

//This PDP context ID is for GPS PD connection, 3 should be reserved for GPS.
#define INTERNAL_AGPS_PDP_CONTEXT 3

// Parameters for AGPS file download thread
typedef struct tagAgpsDownloadParams {
WCHAR wszFile[MAX_PATH];
WCHAR wszURL[MAX_PATH];
HANDLE hDownloadEvent;
} AGPS_DOWNLOAD_PARAMS, *PAGPS_DOWNLOAD_PARAMS;

//For internal AGPS engine mode
enum ENGINE_MODE{
	ENGINEMODE_NONE = 0,
	ENGINEMODE_ASSISTED,
	ENGINEMODE_BASED,
	ENGINEMODE_STANDALONE,
	ENGINEMODE_ALL
};


HRESULT ParseGetCurrentAssistDate(LPCSTR szRsp, void*& pBlob, UINT& cbBlob, LPVOID pParam);

HRESULT ParseGetCurrentAPN(LPCSTR szRsp, void*& pBlob, UINT& cbBlob, LPVOID pParam);

class CGpsHandling {
public:
  CGpsHandling();
  ~CGpsHandling();
  BOOL   Init(CRilHandle* pRilDevice);
  BOOL   Deinit(void);
  BOOL   IsGpsActive(void) { SYNCBLOCK(m_csLock); return (WaitForSingleObject(m_hCloseEvent, 0) != WAIT_OBJECT_0); };
  BOOL   IsGpsLocked(void) { SYNCBLOCK(m_csLock); return (WaitForSingleObject(m_hLockEvent, 0) != WAIT_OBJECT_0); };
  void   ForceDeactivate(void);
  void   ForceDeactivateAsync(void);
  BOOL   SwitchGpsState(BOOL fEnable);
  BOOL   LockGpsAccess(BOOL fLock);
  BOOL   SwitchGpsStatePassive(BOOL fEnable);
  void   DisableGpsStatePassiveAsync(void);
  DWORD  Read(LPVOID pBuf, DWORD dwLen);
  DWORD  Write(LPCVOID pBuf, DWORD dwLen);
  BOOL   IoControl(DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActOut);
  void   TriggerAGPSUpload(void) { SetEvent(m_hAGPSUploadEvent); };
  void   StartWaitForAGPSUpload(void) { ResetEvent(m_hAGPSUploadEvent); };
  void   WaitForAGPSUpload(void) { (void)WaitForSingleObject(m_hAGPSUploadEvent, 2500);};
  BOOL   ConfigureGpsSettings(BOOL *pbNeedRestart) const;

private:
  void   LoadAGPSParameters(void);
  void   PerformInternalAGPSStart(void);
  BOOL SetupAssistGPSConnection(void);
  void ReleaseAssistGPSConnection(void);
  void   AdvancedGPSConfiguration() const;
  BOOL   GetAGPSFile(char *szFilename, DWORD *pdwFileSize);
  BOOL   RemoveAGPSFile(void) const;
  BOOL   CheckAGPSFile(WCHAR *wszFilename, DWORD *pdwFileSize) const;
  BOOL   NeedAGPSDownload(void) const;
  void   ApplyNmeaFrequencySetting(void) const;
  DWORD  NmeaRegChangeHandler();
  static DWORD WINAPI NmeaRegChangeThread(LPVOID lpParameter);
  const char* GetSGPSCfromSGPSS(DWORD dwGpsCmdParam) const { return ((dwGpsCmdParam == 1 || dwGpsCmdParam ==3) ? "off" : "on"); };

  CRilHandle*       m_pRilDevice;
  CRITICAL_SECTION  m_csLock;
  HANDLE            m_hPort;
  HANDLE            m_hCloseEvent;
  HANDLE            m_hLockEvent;
  HANDLE            m_hAGPSUploadEvent;
  HANDLE            m_hAGPSDownloadEvent;
  HANDLE            m_hNmeaRegChangeThread;
  BOOL              m_fNmeaRegChangeThreadRunning;
  HANDLE            m_hNmeaRegChangeThreadCloseEvent;
  BOOL              m_fGpsPassive;
  FILETIME          m_tLastDownload;
  BOOL              m_fConfigureGpsOnPassiveMode;
  BOOL				m_fAssistGPSConnection;
  DWORD             m_dwEngineStatus;
};

// Currently access to the CGpsHandling is realized via a single global variable
extern CGpsHandling g_GpsHandling;

