/*****************************************************************************
 * Copyright (C) Gemalto M2M GmbH
 *****************************************************************************
 * Project: IMC-RIL-Driver
 *****************************************************************************
 * Author : Wireless Modules RD SW A2
 *****************************************************************************
 * $Workfile: Y:/z_ms-d/src/working/Quinn/RilDrv/command.h $
 * $Revision: /main/ms-d/16 $
 *     $Date: 2011-01-18 15:06:18 $
 *   $Author: ctna0256 $
 *****************************************************************************
 * Target:
 *  Microsoft Windows Mobile 5.0
 *****************************************************************************
 * Description:
 *  Gemalto IMC RIL
 *****************************************************************************
 *
 * $Log: Y:/z_ms-d/src/working/Quinn/RilDrv/command.h$ 
 * 
 * /main/ms-d/16   2011-01-18 15:06:18   ctna0256 
 * New syntax for loading A-GPS files
 *
 * /main/ms-d/15   2010-11-01 08:13:24   ctna0256
 * Merge fix for exception in command handling from Classic RIL (IPIS100068178)
 *
 * /main/ms-d/14   2009-10-07 09:22:16   ctna0256
 * Introduce no-operation command queue
 * Support 2nd alpha identifier in SAT setup call (IPIS100055375)
 *
 * /main/ms-d/13   2009-05-20 09:30:43   ctna0256
 * Removed unused command option
 *
 * /main/ms-d/12   2009-02-23 13:15:58   ctna0256
 * Avoid unwanted E_FAIL error codes
 *
 * /main/ms-d/11   2009-01-16 12:44:28   ctna0450
 * New mechanism to prevent PPP data from slip into the AT response buffer
 *
 * /main/ms-d/10   2008-08-22 10:23:23   ctna0256
 * Set Cinterion copyright text
 *
 * /main/ms-d/9   2008-08-21 09:34:14   ctna0256
 * Prepared for new disclaimer handling
 *
 * /main/ms-d/8   2008-06-12 11:34:24   mp49210
 * New option: retry on invalid index
 *
 * /main/ms-d/7   2008-06-06 15:26:37   mp49210
 * New command option Plan_B
 *
 * /main/ms-d/6   2008-04-03 16:13:06   mp49210
 * Don't repeat AT+CRSM=192 if SIM is not inserted
 *
 * /main/ms-d/5   2008-03-13 11:53:04   mp49210
 * Introduction of retry while radio off option
 *
 * /main/ms-d/4   2007-02-09 15:15:42   mp49210
 * Lint compatibility
 *
 * /main/ms-d/3   2006-12-27 14:19:59   mp49210
 * Workaround for wrong CME-error at AT+CPBR
 *
 * /main/ms-d/2   2006-11-13 10:05:11   mp49210
 * New PIN2 handling in Quinn
 *
 * /main/ms-d/1   2006-10-25 16:53:16   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

//
// Forward declarations
//
class CRilInstanceHandle;
class CNotificationData;
enum APIID;

//
// Command options
//
#define CMDOPT_NONE                     0x00000000
#define CMDOPT_IGNORERSP                0x00000001
#define CMDOPT_INIT                     0x00000002
#define CMDOPT_REINIT                   0x00000004
#define CMDOPT_HANGUP                   0x00000008
#define CMDOPT_DIAL                     0x00000010
#define CMDOPT_ANSWER                   0x00000020
#define CMDOPT_GENERALINIT              0x00000040
#define CMDOPT_URC                      0x00000080
#define CMDOPT_NOOP                     0x00000100
#define CMDOPT_POWER                    0x00000200
#define CMDOPT_FINALINIT                0x00000400
#define CMDOPT_RETRYONSIMLOCKED         0x00000800
#define CMDOPT_IGNORERADIOOFF           0x00001000
#define CMDOPT_SETRADIOON               0x00002000
#define CMDOPT_SIMQUERY                 0x00004000
#define CMDOPT_DELAYCONNECTRSP          0x00008000
#define CMDOPT_LONGDIALSTRING           0x00010000
#define CMDOPT_SUPPRESSLOGGING          0x00020000
#define CMDOPT_UNLOCKING                0x00040000
#define CMDOPT_RETRYONRADIOOFF          0x00080000
#define CMDOPT_PLAN_B                   0x00100000
#define CMDOPT_RETRYONINVALIDINDEX      0x00200000
#define CMDOPT_INTERMEDIATERESPONSE     0x00400000
#define CMDOPT_SMSACK                   0x00800000
#define CMDOPT_DIALDATA                 0x01000000
#define CMDOPT_GENERATE_ERROR_CODE      0x02000000
#define CMDOPT_LOWESTPRIO               0x04000000

//
// Command priorities
//
#define CMDPRI_CRITICAL                 0
#define CMDPRI_HIGHEST                  1
#define CMDPRI_HIGH                     2
#define CMDPRI_NORMAL                   3
#define CMDPRI_LOW                      4
#define CMDPRI_LOWEST                   5

//
// Parsing callback stored in CCommand
//
typedef HRESULT (*PFN_CMD_PARSE)(LPCSTR szRsp, void*& pBlob, UINT& cbBlob, LPVOID pParam);
typedef HRESULT (*PFN_CMD_ERROR)(LPCSTR szRsp, void*& pBlob, UINT& cbBlob, LPVOID pParam, DWORD& dwCode);
typedef HRESULT (*PFN_PRE_CMD_CHECK)(CRilHandle *, COM_PORT_TYPE);


struct CME_TRANSLATION {
  HRESULT hrModuleErrorCode;
  HRESULT hrMicrosoftErrorCode;
};


//
// Enum defining the available options of the HC modules on which ports
// commands can be or have to be executed.
//
typedef enum _HCCMD_MODE {
  HCCMD_INVALID = -1,     // Identifier identifying invalid cmd state
  HCCMD_STANDARD,         // Cmd has to be executed on data port when not in data mode, on URC port otherwise
  HCCMD_DATAPORT_ONLY,    // Cmd can be executed on data port only no matter if in data mode or not
  HCCMD_URCPORT_ONLY,     // Cmd can be executed on urc port only
  HCCMD_NOOP_PORT         // Cmd doesn't actually needs to be send to the radio (no-operation commands)
} HCCMD_MODE, *PHCCMD_MODE;


//
// AT command
//
class CCommand : public CListElem
{
public:
                          CCommand();
                          ~CCommand();

  BOOL                    Init(CRilInstanceHandle* const pHandle, const LPCSTR szCmd, const LPCSTR szCmdPart2, const DWORD dwOptions, const HCCMD_MODE CmdMode,
                               const DWORD dwTimeout, CNotificationData* const pnd, const PFN_CMD_PARSE pfnParse,
                               const DWORD dwRetriesOnError, const DWORD dwRetryOnErrorDelay, const APIID apiid,
                               const PFN_CMD_ERROR pfnError = NULL, const LPVOID pParseParam = NULL, const CME_TRANSLATION *pCMET = NULL,
                               PFN_PRE_CMD_CHECK pfnPreCheck = NULL);
  BOOL                    Init(CCommand* pCmd, BOOL bClone);
  void                    SendResponse(const DWORD dwResponseCode, const void* const pBlob, const UINT cbBlob);
  CRilInstanceHandle*     GetHandle(void) const           { return m_pHandle; };
  LPSTR                   GetCmd(void) const              { return m_szCmd; };
  LPSTR                   GetCmdPart2(void) const         { return m_szCmdPart2; };
  const CME_TRANSLATION*  GetCMET(void) const             { return m_pCMET; };
  HRESULT                 GetID(void) const               { return m_hrCmdID; };
  void                    ClearHandle(void)               { m_pHandle = NULL; };
  BOOL                    FIgnoreRsp(void) const          { return (m_dwOptions & CMDOPT_IGNORERSP); };
  BOOL                    FInit(void) const               { return (m_dwOptions & CMDOPT_INIT); };
  BOOL                    FReinit(void) const             { return (m_dwOptions & CMDOPT_REINIT); };
  BOOL                    FHangup(void) const             { return (m_dwOptions & CMDOPT_HANGUP); };
  BOOL                    FDial(void) const               { return (m_dwOptions & CMDOPT_DIAL); };
  BOOL                    FDialData(void) const           { return (m_dwOptions & CMDOPT_DIALDATA); };
  BOOL                    FAnswer(void) const             { return (m_dwOptions & CMDOPT_ANSWER); };
  BOOL                    FGeneralInit(void) const        { return (m_dwOptions & CMDOPT_GENERALINIT); };
  BOOL                    FFinalInit(void) const          { return (m_dwOptions & CMDOPT_FINALINIT); };
  BOOL                    FNoOp(void) const               { return (m_dwOptions & CMDOPT_NOOP); };
  BOOL                    IsSMSAck(void) const            { return (m_dwOptions & CMDOPT_SMSACK); };
  BOOL                    FPower(void) const              { return (m_dwOptions & CMDOPT_POWER); };
  BOOL                    FPlanB(void) const              { return (m_dwOptions & CMDOPT_PLAN_B); };
  BOOL                    FUrc(void) const                { return (m_dwOptions & CMDOPT_URC); };
  BOOL                    FLowestPrio(void) const         { return (m_dwOptions & CMDOPT_LOWESTPRIO); };
  BOOL                    CmdOptIsSet(DWORD Flag) const   { return (m_dwOptions & Flag) ? TRUE : FALSE; }
  void                    SetCmdOpt(DWORD Flag)           { m_dwOptions |= Flag; }
  void                    ClrCmdOpt(DWORD Flag)           { m_dwOptions &= ~Flag; }
  BOOL                    UsePlanB(void);
  DWORD                   GetTimeout(void) const          { return m_dwTimeout; };
  HCCMD_MODE              GetCmdMode(void) const          { return m_CmdMode; };
  LPVOID                  GetParseParam(void) const       { return m_pParseParam; };
  CNotificationData*      GiveUpNotificationData(void)    { CNotificationData* pnd = m_pndNotify; m_pndNotify = NULL; return pnd; };
  PFN_PRE_CMD_CHECK       GetPreCheckFunc(void) const     { return m_pfnPreCheck; };
  APIID                   GetAPIID(void) const            { return m_apiid; };
  BOOL                    ResultHandlerAvailable(BOOL fOk) const { return (fOk ? (m_pfnParseOk != NULL) : (m_pfnParseError != NULL)); };
  HRESULT                 CallResultHandler(DWORD& dwCode, LPCSTR strResult, void*& pBlob, UINT& uiBlob);
  DWORD                   GetPriority(void) const;
  BOOL                    RetryCommandOnError(void);
  HRESULT                 TranslateErrorCode(HRESULT hrModule) const;

protected:
  CRilInstanceHandle*     m_pHandle;
  DWORD                   m_dwOptions;

private:
  LPSTR                   m_szCmd;
  LPSTR                   m_szCmdPart2;
  const CME_TRANSLATION*  m_pCMET;
  HRESULT                 m_hrCmdID;
  DWORD                   m_dwTimeout;
  CNotificationData*      m_pndNotify;
  PFN_CMD_PARSE           m_pfnParseOk;
  PFN_CMD_ERROR           m_pfnParseError;
  PFN_PRE_CMD_CHECK       m_pfnPreCheck;
  LPVOID                  m_pParseParam;
  DWORD                   m_dwRetriesOnError;
  DWORD                   m_dwRetryOnErrorDelay;
  DWORD                   m_dwThreadPermission;
  APIID                   m_apiid;
  HCCMD_MODE              m_CmdMode;
};

