/*****************************************************************************
 * Copyright (C) Gemalto M2M GmbH
 *****************************************************************************
 * Project: IMC-RIL-Driver
 *****************************************************************************
 * Author : Wireless Modules RD SW A2
 *****************************************************************************
 * $Workfile: Y:/z_ms-d/src/working/Quinn/RilDrv/response.h $
 * $Revision: /main/ms-d/40 $
 *     $Date: 2013-10-01 14:13:20 $
 *   $Author: pmackent $
 *****************************************************************************
 * Target:
 *  Microsoft Windows Mobile 5.0
 *****************************************************************************
 * Description:
 *  Gemalto IMC RIL
 *****************************************************************************
 *
 * $Log: Y:/z_ms-d/src/working/Quinn/RilDrv/response.h$ 
 * 
 * /main/ms-d/40   2013-10-01 14:13:20   pmackent 
 * Solved problem when a concatenated AT command with an AT+CREG/+CGREG in front fails with an CME error
 *
 * /main/ms-d/39   2013-09-13 09:27:19   pmackent
 * Cell Broadcast for CDMA (IPIS100091379)
 *
 * /main/ms-d/38   2013-05-21 11:45:52   pmackent
 * Allow user defined OMADM textes
 *
 * /main/ms-d/37   2013-04-26 09:17:19   pmackent
 * Parsing of CDMA status reports added
 *
 * /main/ms-d/36   2013-02-26 15:07:50   pmackent
 * Adaptions for EHS5 1.290
 *
 * /main/ms-d/35   2013-02-01 14:24:20   pmackent
 * Handling of OMADM URC
 *
 * /main/ms-d/34   2012-12-12 15:24:21   pmackent
 * Workarounds for bugs in PXS8 2.821
 *
 * /main/ms-d/33   2012-06-05 11:47:45   pmackent
 * Add handling of undocumented CDMA activation URC (IPIS100079730)
 *
 * /main/ms-d/32   2012-04-18 13:47:15   ctna0256
 * Introducing PVS8
 * Implementing CDMA-SMS
 * Various CDMA enhancements
 *
 * /main/ms-d/31   2012-02-22 13:27:06   ctna0256
 * Encapsulate use of Intel AT command set
 *
 * /main/ms-d/30   2012-02-14 15:13:15   ctna0256
 * Handle URCs within responses.
 *
 * /main/ms-d/29   2012-02-08 15:15:47   ctna0256
 * Add Intel-style SAT
 *
 * /main/ms-d/27   2012-02-03 15:07:28   ctna0256
 * Move URC parsing functions in separate file
 *
 * /main/ms-d/26   2012-02-02 17:03:52   ctna0256
 * FD phonebook workaround and NITZ URCs for Intel platform
 *
 * /main/ms-d/25   2012-01-31 16:38:51   ctna0256
 * Added support for EHS5
 *
 * /main/ms-d/24   2012-01-17 10:22:27   ctna0256
 * Workaround for wrong indication of "+CIEV: psinfo,6" (IPIS100076880)
 *
 * /main/ms-d/23   2012-01-03 15:46:44   ctna0256
 * Introduce PXS8
 *
 * /main/ms-d/22   2011-07-07 10:33:29   ctna0256
 * Handle unusual long "SIM busy" state on some SIM cards with the PH8 Rel2
 *
 * /main/ms-d/21   2011-02-02 10:58:23   ctna0256
 * Earlier CSQ notifications
 *
 * /main/ms-d/20   2010-09-08 11:24:37   ctna0256
 * RIL option: automatic GPRS reattach (IPIS100064423)
 *
 * /main/ms-d/19   2010-06-03 11:31:10   ctna0256
 * New psinfo value 11
 *
 * /main/ms-d/18   2010-06-01 15:24:05   ctna0256
 * New psinfo values
 *
 * /main/ms-d/17   2008-10-21 10:03:05   ctna0256
 * Query status of call meter after unsuccessful dial attempt
 *
 * /main/ms-d/16   2008-08-22 10:26:35   ctna0256
 * Set Cinterion copyright text
 *
 * /main/ms-d/15   2008-08-21 09:35:11   ctna0256
 * Prepared for new disclaimer handling
 *
 * /main/ms-d/14   2008-06-20 11:05:53   mp49210
 * Remove unused SIEMENS_MAGNETO define
 *
 * /main/ms-d/13   2008-04-29 13:38:03   mp49210
 * Workaround for missing simstatus URC.
 * New handling of SIM reset.
 *
 * /main/ms-d/12   2008-01-17 15:26:00   mp49210
 * Fix for slow UICC SIMs (wrong SIM not inserted error)
 *
 * /main/ms-d/11   2007-11-01 14:36:50   mp49210
 * Handle new ^SCRD: URC
 *
 * /main/ms-d/10   2007-10-11 16:23:15   mp49210
 * Introduction of AT^SLCC
 *
 * /main/ms-d/9   2007-05-29 09:37:03   mp49210
 * Workaoround for wrong error code to AT+CPIN?
 *
 * /main/ms-d/8   2007-04-24 15:58:19   mp49210
 * IPIS100035501: introduction of list of networks (registry), where the RIL should not send the roaming status
 *
 * /main/ms-d/7   2007-02-16 10:05:30   mp49210
 * Handle error causes for GCF approval
 *
 * /main/ms-d/6   2007-02-09 16:02:33   mp49210
 * PreFast compatibility
 *
 * /main/ms-d/5   2007-01-04 13:46:54   mp49210
 * Introduction of SHUTDOWN: URC
 *
 * /main/ms-d/4   2006-12-20 11:32:59   mp49210
 * Report system capabilities for voice+data according AT^SIND=psinfo
 *
 * /main/ms-d/3   2006-12-18 17:46:09   mp49210
 * Introduction of AT^SIND=psinfo
 *
 * /main/ms-d/2   2006-11-02 09:37:51   mp49210
 * No AT^SLCC in Quinn
 *
 * /main/ms-d/1   2006-10-25 16:51:34   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

// Used by CResponse
#define ALLOC_SIZE                      1024

//
// Error mapping structure used for binary search
//
struct ERRORMAP {
    HRESULT hrError;
    DWORD dwCode;
};

#ifdef RIL_ADVANCEDUSSDERRORCAUSES
//
// AT+CMEE error causes
//
struct CMEERRORCAUSE
{
    DWORD   dwCMEError;
    UINT    uiErrorText;
};
#endif

inline void *AllocBlob(UINT bytes)
{
    return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
}

inline void *FreeBlob(void *pblob)
{
    return (void *)LocalFree(pblob);
}

inline void *ReallocBlob(void *pblob, UINT bytes)
{
    if (!pblob)
    {
        return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
    }

    return (void *)LocalReAlloc(pblob,bytes,LMEM_MOVEABLE);
}

class CRilHandle;
//
// AT command response
//
class CResponse : public CBuffer
{
public:
            CResponse(COM_PORT_TYPE PortType, CRilHandle *pRilHandle);
            ~CResponse();
            CResponse(const CResponse &Rsp);

    BOOL    AppendString(LPSTR szString, const UINT cbString, LPCSTR& rszRemainder, UINT& rcbRemainder);
    BOOL    SetBlob(const void* const pBlob, const UINT cbBlob);
    BOOL    MakeError(const HRESULT hr);
    void    DeleteBlob(void)                            { (void)FreeBlob(m_pBlob); m_pBlob = NULL; m_cbBlob = 0; return; };
    void    MakeOK(void)                                { m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; return; };
    BOOL    ParseOKOrErrorData(CCommand*&rpCmd, BOOL fCmdOk);
    HRESULT GetError(void) const;
    void    GetBlob(void*& rpBlob, UINT& rcbBlob) const { rpBlob = m_pBlob; rcbBlob = m_cbBlob; return; };
    DWORD   GetNotifyCode(void) const                   { return m_dwCode; };
    BOOL    FUnsolicited(void) const                    { return !!m_fUnsolicited; };
    BOOL    FUnrecognized(void) const                   { return !!m_fUnrecognized; };
    void    ConnectToOK(void)   { m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; return; };
    void    NoCarrierToOK(void) { m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; return; };
    void    SetCallAborted(void) { m_dwCode = RIL_RESULT_CALLABORTED; m_fUnsolicited = FALSE; return; };
    BOOL    OKToError(HRESULT hr);
    void    SetPotentialBogusResponseFlag(void) { m_fPotentialBogusResponse = TRUE; return; }

private:
    BOOL    SearchV1Response(LPCSTR& szPointer, UINT *uiRetCode) const;
    BOOL    Parse(UINT& rcbNewLength);
    BOOL    ParseOKOrError(const BOOL fOK, UINT& rcbNewLength);
    BOOL    ParseNotification(UINT& rcbNewLength);
    BOOL    ParseV25Response(UINT nResponseCode);
    BOOL    ParseExtError(LPCSTR& rszPointer, const ERRORMAP* const rgemMap, const UINT nMapEntries, UINT &nCode, BOOL fSigned);
    BOOL    ParseExtRing(LPCSTR& rszPointer, DWORD *pdwCallType);
    BOOL    ParseServiceInfo(LPCSTR& rszPointer);
    BOOL    ParseRemotePartyInfo(LPCSTR& rszPointer, BOOL fCLIP);
    BOOL    ParseCallWaitingInfo(LPCSTR& rszPointer);
    BOOL    ParseUnsolicitedSSInfo(LPCSTR& szPointer);
    BOOL    ParseIntermediateSSInfo(LPCSTR& szPointer);
    BOOL    ParseCallMeter(LPCSTR& rszPointer);
    BOOL    ParseCallListNotification(LPCSTR& rszPointer);
    BOOL    ParseIndicatorEventValue(LPCSTR& rszPointer);
#ifdef RIL_ENABLE_ALS
    BOOL    ParseALSStatusStatus(LPCSTR& rszPointer);
#endif
    BOOL    ParseRegistrationStatus(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseCdmaRegistrationStatus(LPCSTR& rszPointer);
    BOOL    ParseSIMCardStatus(LPCSTR& rszPointer, BOOL bSCKSURC);
    BOOL    ParseExtendedShutdown(LPCSTR& rszPointer, BOOL &bShutdown) const;
    BOOL    ParseTemperatureWarning(LPCSTR& rszPointer, INT &iCause) const;
    BOOL    ParseUSSDInfo(LPCSTR& rszPointer, BOOL &fExpectNothing);
    BOOL    ParseMessage(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseCdmaMessage(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseCdmaQCBMessage(LPCSTR& rszPointer);
    BOOL    ParseMessageInSim(LPCSTR& rszPointer, DWORD const dwNotifyCode, BOOL fNoNotification = FALSE);
    BOOL    ParseCdmaMessageInMemory(LPCSTR& rszPointer);
    BOOL    ParseCdmaActivation(LPCSTR& rszPointer);
    void    TransformOMADMText(const char* szOMADMResponse, WCHAR *wszActivationResponse, UINT uiBufferLen);
    BOOL    ParseOMADMNotification(LPCSTR& rszPointer);
    BOOL    ParseSIMToolkitCmdOrRsp(LPCSTR& rszPointer, const DWORD dwNotifyCode);
    BOOL    ParseSIMToolkitCallSetup(LPCSTR& rszPointer);
    BOOL    ParseTimeZoneNotification(LPCSTR& rszPointer);
    BOOL    ParseDayLightSavingNotification(LPCSTR& rszPointer);
#ifdef SUPPORTS_EHSX_R1
    BOOL    ParseXCievNotification(LPCSTR& szPointer);
    BOOL    ParseXregNotification(LPCSTR& szPointer);
#endif
    void    ParseJunk(UINT nCRLFs, LPCSTR& rszPointer);
    BOOL    ParseRadioSysstart(LPCSTR& rszPointer);
    BOOL    ParseRadioShutdown(LPCSTR& rszPointer);
    BOOL    IsProbablyNotUCS2(LPCSTR szDataString) const;
#ifdef SUPPORTS_EHSX_R1
    BOOL    IsRelevantURC(char *szStart, UINT uiLenBuffer, UINT *puiLenLine) const;
    void    FindNotificationInResponse();
#endif
    void    UpdateCallStatusAfterRing(DWORD dwCallType) const;
    BOOL    IsUrcOrResponse(LPCSTR szPointer) const;

    DWORD          m_dwCode;
    void*          m_pBlob;
    UINT           m_cbBlob;
    DWORD          m_fUnsolicited : 1;
    DWORD          m_fUnrecognized : 1;
    DWORD          m_fPotentialBogusResponse : 1;
    COM_PORT_TYPE  m_PortType;
    RILCALLINFO    m_CallInfo[MAX_NUMBERCALLS];
    UINT           m_iNrCallInfo;
    CRilHandle*    m_pRilHandle;
};


//
// Notification data
//
class CNotificationData
{
public:
                        CNotificationData();
                        ~CNotificationData();

    BOOL                InitFromDWORDBlob(const DWORD dwCode, const DWORD dwBlob);
    BOOL                InitFromRealBlob(const DWORD dwCode, const void* const pBlob, UINT cbBlob);
    BOOL                FinishInitFromRspBlob(const CResponse& rRsp);
    BOOL                DelayInitFromRspBlob(const DWORD dwCode);

    BOOL                FDelayedInitFromRsp(void) const { return !!m_fDelayedInitFromRsp; };
    DWORD               GetCode(void) const             { return m_dwCode; };
    const void* const   GetBlob(void) const             { return m_pBlob; };
    UINT                GetSize(void) const             { return m_cbBlob; };

private:
    DWORD       m_dwCode;
    void*       m_pBlob;
    UINT        m_cbBlob;
    DWORD       m_fInited : 1;
    DWORD       m_fDelayedInitFromRsp : 1;
};

HRESULT FindCMEErrorCode(UINT nCMEError);
