/*****************************************************************************
 * Copyright (C) Gemalto M2M GmbH
 *****************************************************************************
 * Project: IMC-RIL-Driver
 *****************************************************************************
 * Author : Wireless Modules RD SW A2
 *****************************************************************************
 * $Workfile: Y:/z_ms-d/src/working/Quinn/RilDrv/comhand.h $
 * $Revision: /main/ms-d/20 $
 *     $Date: 2013-06-27 16:00:03 $
 *   $Author: pmackent $
 *****************************************************************************
 * Target:
 *  Microsoft Windows Mobile 5.0
 *****************************************************************************
 * Description:
 *  Gemalto IMC RIL
 *****************************************************************************
 *
 * $Log: Y:/z_ms-d/src/working/Quinn/RilDrv/comhand.h$ 
 * 
 * /main/ms-d/20   2013-06-27 16:00:03   pmackent 
 * Adaptions for EHS5 Rel1->Rel2 update
 *
 * /main/ms-d/19   2013-04-29 16:20:14   pmackent
 * Improved deactivation of data connections
 *
 * /main/ms-d/18   2010-09-23 13:52:13   ctna0256
 * Workaround for DSR problem in PH8 customer sample
 *
 * /main/ms-d/17   2010-08-19 14:29:57   ctna0256
 * Implementation A-GPS for PH8
 *
 * /main/ms-d/16   2009-02-10 11:09:36   ctna0450
 * Broadcast disconnect notifications always when data mode has been left
 *
 * /main/ms-d/15   2009-02-02 15:23:18   ctna0450
 * Fixed restauration of external WaitCommMask after port reopen
 *
 * /main/ms-d/14   2009-01-16 12:44:24   ctna0450
 * New mechanism to prevent PPP data from slip into the AT response buffer
 *
 * /main/ms-d/13   2009-01-14 10:49:58   ctna0450
 * Removed special handling for consecutive WaitCommEvent() calls because mux ports are properly instancable now
 *
 * /main/ms-d/12   2008-08-22 10:22:59   ctna0256
 * Set Cinterion copyright text
 *
 * /main/ms-d/11   2008-08-21 09:34:05   ctna0256
 * Prepared for new disclaimer handling
 *
 * /main/ms-d/10   2008-07-15 14:01:14   mp49210
 * New option: RIL_FILTER_PIN_IN_RETAIL_OUTPUT
 *
 * /main/ms-d/9   2008-05-30 13:31:19   ht37010
 * bugfix for IPIS 47799:
 * added protoypes to synchronize WaitOnMask() calls from CheckCmdModeThread and the thread that uses the external data port (i.e. PPP)
 *
 * /main/ms-d/8   2008-04-03 14:41:25   mp49210
 * Introduction of new debug zones
 *
 * /main/ms-d/7   2007-11-02 15:50:09   ht37010
 * fix for EPIC21309: passing parameter to avoid waiting for reopen if module is already powered off
 *
 * /main/ms-d/6   2007-10-12 09:54:52   mp49210
 * Workaround for problem with temporary unavailable status line query command
 *
 * /main/ms-d/5   2007-07-18 17:09:21   ht37010
 * IPIS100039395: corrected handling of closing data connection during a suspend-resume-cycle
 *
 * /main/ms-d/4   2007-02-15 12:09:12   wm36264
 * Added port reopen after resume as workaround for USB reset problem
 *
 * /main/ms-d/3   2006-11-14 16:59:57   wm36264
 * Tidy up more unused stuff
 *
 * /main/ms-d/2   2006-11-09 12:24:24   wm36264
 * Removed some obsolete parameters
 *
 * /main/ms-d/1   2006-10-25 16:53:02   wm36264
 * First transformation from classic RIL
 *
*/

//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2008 Gemalto M2M GmbH
// Copyright (C) 2006-2008 Siemens AG
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//
// Version: 1.0
// Date:    dummy
//
//////////////////////////////////////////////////////////////////////////////

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1999  Microsoft Corporation
--*/

#pragma once

//
// Defines
//

#define STAT_BUCKETS                10
#define STAT_BUCKET_WEIGHTS         (STAT_BUCKETS * (STAT_BUCKETS + 1) / 2)

#define CMD_MODE_MASK               (EV_DSR | EV_RLSD)
#define CMD_MODE_STATUS             (MS_DSR_ON | MS_RLSD_ON)
#define CMD_MODE_STATUS_NO_DSR      (MS_RLSD_ON)

#define MIN_TIME_BEFORE_ABORT       200

#define ABORT_COMMAND               "\r\r\033"
#define ABORT_COMMAND_SIZE          strlen(ABORT_COMMAND)

#define REOPEN_TIMEOUT              10000
#define FIRSTCOMSTATUS_TIMEOUT      5000

// Open port: default delay and retries
#define DEFAULT_PORT_TIMEOUT  1000
#define DEFAULT_PORT_RETRIES  10

//
// Forward declarations
//
class CComInstanceHandle;

//
// Virtual serial device handle
//
class CComHandle
{
public:
               CComHandle(COM_PORT_TYPE PortType);
               ~CComHandle();

  COM_PORT_TYPE GetPortType(void) const { return m_PortType; };
  BOOL         Init(void);
  BOOL         OpenDownstreamPort(CRilHandle *pRilHandle);
  BOOL         CloseDownstreamPort(BOOL fKeepData);
  void         SetExternalCancelEvent(HANDLE hEvent) { SYNCBLOCK(m_csPortHandle); m_hExternalCancelEvent = hEvent; };
  BOOL         WriteCharsToComPort(LPCSTR szChars, UINT cbToWrite, BOOL fLimitedLogging);
  BOOL         WriteCmdsToComPort (LPCSTR szChars, UINT cbToWrite, BOOL fLimitedLogging);
  BOOL         WriteBinaryToComPort(BYTE *pBytes, UINT cbToWrite);
  void         LockRILCmd(void) { EnterCriticalSection(&m_csAbortCommand); };
  void         UnlockRILCmd(void) { LeaveCriticalSection(&m_csAbortCommand); };
  BOOL         SendRILCmdHandleRsp(CRilHandle* const pRilDevice, CCommand*& rpCmd);
  BOOL         EnterDataMode(void);
  BOOL         ExitDataMode( BOOL fReopen = TRUE );
  BOOL         TerminateDataMode(void);
  BOOL         SwitchBackToCommandMode(void);
  BOOL         FDataMode(void) { SYNCBLOCK(m_csDataMode); return m_fDataMode; };
  void         StopWaitDataMode(void) { SYNCBLOCK(m_csDataMode); m_fWaitDataMode = FALSE; };
  BOOL         FWaitDataMode(void) { SYNCBLOCK(m_csDataMode); return m_fWaitDataMode; };
  BOOL         FDataCsdMode(void);
  BOOL         WaitForCommandMode(DWORD dwTimeOut = INFINITE) const;
  BOOL         AbortCommand(void);
  BOOL         InitComPortForRIL(DCB* const pdcbOld, COMMTIMEOUTS* const pctOld) const;
  BOOL         SetOwner(const CComInstanceHandle* const pHandle);
  BOOL         ClearOwner(const CComInstanceHandle* const pOwner);
  BOOL         FHandleIsOwner(const CComInstanceHandle* const pHandle)
                 { SYNCBLOCK(m_csOwner); return (pHandle == m_pOwner); };
  void         UpdateComStatData(const BOOL fRead, const DWORD dwBytes);
  void         CalculateComStats(DWORD& rdwReadBitsPerSec, DWORD& rdwWrittenBitsPerSec);
  void         SetCancelledDial(void) { m_fCancelledDial = TRUE; }

  BOOL         VirtRead(void* pBuf, const UINT cb, DWORD& rdwRead) const;
  BOOL         VirtWrite(const void* pBuf, const UINT cb, DWORD& rdwWritten);
  BOOL         VirtIOControl(const DWORD dwCode, const BYTE* const pBufIn, const DWORD dwLenIn, BYTE* const pBufOut,
                             const DWORD dwLenOut, DWORD& rdwActualOut, BOOL fLockSignals);
  BOOL         VirtWaitCommEvent(DWORD* const pdwMask) const;
  BOOL         VirtClearCommBreak(BOOL fReopen=TRUE) const;
  BOOL         VirtClearCommError(DWORD* const pdwErrors, COMSTAT* const pcs, BOOL fReopen=TRUE) const;
  BOOL         VirtEscapeCommFunction(const DWORD dwFunc) const;
  BOOL         VirtGetCommMask(DWORD* const pdwMask) const;
  BOOL         VirtSetCommMask(const DWORD dwMask, BOOL fReopen=TRUE);
  BOOL         VirtGetCommModemStatus(DWORD* const pdwStatus, DWORD dwTimeout = 0) const;
  BOOL         VirtGetCommProperties(COMMPROP* const pcp) const;
  BOOL         VirtGetCommState(DCB* const pdcb) const;
  BOOL         VirtSetCommState(DCB* const pdcb) const;
  BOOL         VirtGetCommTimeouts(COMMTIMEOUTS* const pct) const;
  BOOL         VirtSetCommTimeouts(COMMTIMEOUTS* const pct) const;
  BOOL         VirtPurgeComm(const DWORD dwFlags, BOOL fReopen=TRUE) const;
  BOOL         VirtSetCommBreak(void) const;
  BOOL         VirtSetupComm(const DWORD dwInQueue, const DWORD dwOutQueue) const;
  BOOL         VirtTransmitCommChar(const char cChar) const;
  BOOL         InitCommState(DCB* const pdcbOld) const;
  DWORD        GetBaudRate(void) const         { return m_dwDownstreamBaudRate; };
  DWORD        GetLastCmdTime(void) const      { return m_dwLastCmdSent; };
  HANDLE       GetPortHandle(void)             { SYNCBLOCK(m_csPortHandle); return m_hDownstream; };
  BOOL         IsDownstreamPortOpen(void)      { SYNCBLOCK(m_csPortHandle); return (m_hDownstream != INVALID_HANDLE_VALUE); };
  BOOL         WaitForDownstreamPort(void);

private:
  BOOL         CmdGetCommModemStatus(DWORD* const pdwStatus, DWORD dwTimeout = 0) const;
  static DWORD WINAPI CheckCmdModeThread(LPVOID lpParam);

  COM_PORT_TYPE               m_PortType;
  HANDLE                      m_hDownstream;
  HANDLE                      m_hChkCmdPort;
  HANDLE                      m_hCComHandleDestroyEvent;
  HANDLE                      m_hCommandModeEvent;
  HANDLE                      m_hComCancelEvent;
  HANDLE                      m_hComInitEvent;
  HANDLE                      m_hExternalCancelEvent;
  DWORD                       m_dwDownstreamBaudRate;
  DWORD                       m_dwStatQuantum;
  DWORD                       m_rgdwReadStatBits[STAT_BUCKETS];
  DWORD                       m_rgdwWriteStatBits[STAT_BUCKETS];
  DWORD                       m_dwReadStatTimestamp;
  DWORD                       m_dwWriteStatTimestamp;
  const CComInstanceHandle*   m_pOwner;
  CRITICAL_SECTION            m_csDataMode;
  CRITICAL_SECTION            m_csOwner;
  CRITICAL_SECTION            m_csStats;
  CRITICAL_SECTION            m_csPortHandle;
  CRITICAL_SECTION            m_csAbortCommand;
  DWORD                       m_fInited : 1;
  DWORD                       m_fDataMode : 1;
  DWORD                       m_fCsdMode : 1;
  DWORD                       m_fWaitDataMode : 1;
  DWORD                       m_fCancelledDial : 1;
  DWORD                       m_dwLastCmdSent;
  DWORD                       m_dwLastDataSent;
  DWORD                       m_dwCurrentMask;
  BOOL                        m_fCommandOngoing;
};


//
// Virtual serial instance handle
//
class CComInstanceHandle
{
public:
                      CComInstanceHandle();
                      ~CComInstanceHandle();

  BOOL                Init(CComHandle* const pDevice, const DWORD dwAccess);
  CComHandle*         GetDevice(void) const    { return m_pDevice; };
  BOOL                IsRsaMode(void) const    { return m_fRsaMode; };

private:
  CComHandle*         m_pDevice;
  BOOL                m_fRsaMode;
};


//
// Virtual serial instance handle for GPS port
//
class CGpsInstanceHandle
{
public:
                      CGpsInstanceHandle() { };
                      ~CGpsInstanceHandle() { };
  BOOL                Open(void) const { RILRetailTraceZone(ZONE_INFO, (TEXT("RilDrv: Opening virtual GPS port\r\n"))); return g_PowerManager.EnterGpsState(TRUE); };
  BOOL                Close(void) const { RILRetailTraceZone(ZONE_INFO, (TEXT("RilDrv: Closing virtual GPS port\r\n"))); return g_PowerManager.EnterGpsState(FALSE); };
  DWORD               Read(LPVOID pBuf, DWORD dwLen) const { return g_GpsHandling.Read(pBuf, dwLen); };
  DWORD               Write(LPCVOID pBuf, DWORD dwLen) const { return g_GpsHandling.Write(pBuf, dwLen); };
  BOOL                IoControl(DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) const
                        { return g_GpsHandling.IoControl(dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut); };
};


//
// Parameter strcuture passed to HangupThreadProc
//
struct HANGUP_THREAD_DATA {
  HANDLE         hQuitEvent;
  CComHandle*    pComDevice;
  CRilHandle*    pRilDevice;
  COM_PORT_TYPE  PortType;
};


#ifndef UNDER_CE
//
// Operlapped operations
//
enum OVERLAPPED_OPER
{
  OVERLAPPED_WAIT = 1,
  OVERLAPPED_READ,
  OVERLAPPED_WRITE
};

//
// Functions
//
BOOL PerformOverlappedIO(const OVERLAPPED_OPER oper, const HANDLE hCom, void* pbData, UINT cbData, DWORD* pdwData);
#endif // UNDER_CE

